diff options
-rw-r--r-- | doc/dw-images-and-backgrounds.doc | 214 | ||||
-rw-r--r-- | dw/imgrenderer.hh | 12 |
2 files changed, 135 insertions, 91 deletions
diff --git a/doc/dw-images-and-backgrounds.doc b/doc/dw-images-and-backgrounds.doc index 429d62f6..e4011848 100644 --- a/doc/dw-images-and-backgrounds.doc +++ b/doc/dw-images-and-backgrounds.doc @@ -1,10 +1,11 @@ /** \page dw-images-and-backgrounds Images and Backgrounds in Dw -<h2>General</h2> +Image Buffers +============= -Representation of the image data is delegated to dw::core::Imgbuf, see -there for details. Drawing is delegated to dw::core::View -(dw::core::View::drawImgbuf). +Representation of the image data is done by dw::core::Imgbuf, see +there for details. Drawing is done by dw::core::View +(dw::core::View::drawImage). Since dw::core::Imgbuf provides memory management based on reference counting, there may be an 1-to-n relation from image renderers (image @@ -15,65 +16,76 @@ dw::core::Imgbuf::copyRow) notify all renderers connected to the buffer. -<h2>Images</h2> +Image Renderer +============== + +Generally, there are no restrictions on how to manage +dw::core::Imgbuf; but to handle image data from web resources, the +interface dw::core::ImgRenderer should be implemented. It is again +wrapped by DilloImago (to make access from the C part possible, since +dw::core::ImgRenderer is written in C++), which is referenced by +DilloWeb. There are two positions where retrieving image data is +initiated: + +- Html_load_image: for embedded images (implemented by dw::Image, + which implements dw::core::ImgRenderer); +- StyleEngine::apply (search for "case + CSS_PROPERTY_BACKGROUND_IMAGE"): for backgrond images; there are + some implementations of dw::core::ImgRenderer within the context of + dw::core::style::StyleImage. + +Both are described in detail below. Notice that the code is quite +similar; only the implementation of dw::core::ImgRenderer differs. + +At this time, dw::core::ImgRenderer has got two methods (see more +documentation there): + +- dw::core::ImgRenderer::setBuffer and +- dw::core::ImgRenderer::drawRow. + +Possible extensions: + +- ''finished'': when all image data has been retrieved; +- ''fatal'': when there are problems with the retrieval of image data. + + +Images +====== This is the simplest renderer, displaying an image. For each row to be drawn, -<ol> -<li> first dw::core::Imgbuf::copyRow, and then -<li> for each dw::Image, dw::Image::drawRow must be called, with the same - argument (no scaling is necessary). -</ol> +- first dw::core::Imgbuf::copyRow, and then +- for each dw::Image, dw::Image::drawRow must be called, with the same + argument (no scaling is necessary). dw::Image automatically scales the dw::core::Imgbuf, the root buffer should be passed to dw::Image::setBuffer. \see dw::Image for more details. -<h2>Future Extensions</h2> -(This is not implemented yet.) Rendering itself (image widgets and -background) will be abstracted, by a new interface -dw::core::ImageRenderer. In the current code for image decoding, this -interface will replace references to dw::Image, which implements -dw::core::ImageRenderer, in most cases. +Background Images +================= -<h2>Backgrounds</h2> +Since background images are style resources, they are associated with +dw::core::style::Style, as dw::core::style::StyleImage, which is +handled in a similar way (reference counting etc.) as +dw::core::style::Color and dw::core::style::Font, although it is +concrete and not platform-dependant. -<div style="border: 2px solid #ffff00; margin-bottom: 0.5em; -padding: 0.5em 1em; background-color: #ffffe0"><b>Info:</b> This -section, which was written long before the implementation, is not up -to date (although the main ideas have not changed).</div> +The actual renderer (passed to Web) is an instance of +dw::core::ImgRendererDist (distributes all calls to a set of other +instances of dw::core::ImgRenderer), which contains two kinds of +renderers: -Since background are style resources, they are associated with -dw::core::style::Style. For backgrounds, another level is needed, -because of the 1-to-n relation from dw::core::style::Style to -dw::core::Widget: +- one instance of dw::core::style::StyleImage::StyleImgRenderer, which + does everything needed for dw::core::style::StyleImage, and +- other renderes, used externally (widgets etc.), which are added by + dw::core::style::StyleImage::putExternalImgRenderer (and removed by + dw::core::style::StyleImage::removeExternalImgRenderer). -\dot -digraph G { - node [shape=record, fontname=Helvetica, fontsize=10]; - edge [arrowhead="open", dir="both", arrowtail="none", - labelfontname=Helvetica, labelfontsize=10, color="#404040", - labelfontcolor="#000080"]; - fontname=Helvetica; fontsize=10; - - "background renderer (as a part of style)" -> "image buffer" [headlabel="*", - taillabel="1"]; - "widget (or a part of it)" -> "background renderer (as a part of style)" - [headlabel="*", taillabel="1"]; -} -\enddot - -Unlike dw::Image, dw::core::style::BgRenderer is not associated with a -certain rectangle on the canvas. Instead, widgets, or parts of widgets -take this role. This is generally represented by an implementation of -the interface dw::core::style::BgAllocation, which is implemented by -dw::core::Widget, but also by all parts of widget implementation, -which may have an own background image. - -The following diagram gives a total overview: +This diagram gives an comprehensive overview: \dot digraph G { @@ -83,70 +95,90 @@ digraph G { labelfontcolor="#000080"]; fontname=Helvetica; fontsize=10; - "DICache Entry"; - - subgraph cluster_dw_images { + subgraph cluster_dw_style { style="dashed"; color="#000080"; fontname=Helvetica; fontsize=10; - label="Dw Images"; - ImageRenderer [URL="\ref dw::core::ImageRenderer", color="#ff8080"]; - Imgbuf [URL="\ref dw::core::Imgbuf", color="#ff8080"]; + Style [URL="\ref dw::core::style::Style"]; + StyleImage [URL="\ref dw::core::style::StyleImage"]; + Imgbuf [URL="\ref dw::core::Imgbuf", color="#a0a0a0"]; + StyleImgRenderer + [URL="\ref dw::core::style::StyleImage::StyleImgRenderer"]; + ImgRenderer [URL="\ref dw::core::ImgRenderer", color="#ff8080"]; + ImgRendererDist [URL="\ref dw::core::ImgRendererDist"]; + ExternalImgRenderer + [URL="\ref dw::core::style::StyleImage::ExternalImgRenderer", + color="#a0a0a0"]; + ExternalWidgetImgRenderer + [URL="\ref dw::core::style::StyleImage::ExternalWidgetImgRenderer", + color="#a0a0a0"]; } - subgraph cluster_widgets { + subgraph cluster_dw_layout { style="dashed"; color="#000080"; fontname=Helvetica; fontsize=10; - label="Widgets"; - Widget [URL="\ref dw::core::Widget", color="#a0a0a0"]; - Textblock [URL="\ref dw::Textblock"]; - "Textblock::Word" [URL="\ref dw::Textblock::Word"]; - Table [URL="\ref dw::Table"]; - "Table::Row" [URL="\ref dw::Table::Row"]; - Image [URL="\ref dw::Image"]; + Layout [URL="\ref dw::core::Layout"]; + LayoutImgRenderer [URL="\ref dw::core::Layout::LayoutImgRenderer"]; } - subgraph cluster_style { + subgraph cluster_dw_widget { style="dashed"; color="#000080"; fontname=Helvetica; fontsize=10; - label="dw::core::style"; - Style [URL="\ref dw::core::style::Style"]; - BgRenderer [URL="\ref dw::core::style::BgRenderer"]; - BgAllocation [URL="\ref dw::core::style::BgAllocation", color="#ff8080"]; + Widget [URL="\ref dw::core::Widget", color="#a0a0a0"]; + WidgetImgRenderer [URL="\ref dw::core::Widget::WidgetImgRenderer"]; } - "DICache Entry" -> ImageRenderer [headlabel="*", taillabel="1"]; - "DICache Entry" -> Imgbuf [headlabel="1", taillabel="1"]; - - BgRenderer -> Imgbuf [headlabel="1", taillabel="*"]; - BgRenderer -> BgAllocation [headlabel="*", taillabel="1"]; - ImageRenderer -> BgRenderer [arrowhead="none", arrowtail="empty", dir="both", - style="dashed"]; - ImageRenderer -> Image [arrowhead="none", arrowtail="empty", dir="both", - style="dashed"]; - - Style -> BgRenderer [headlabel="0..1", taillabel="1"]; + subgraph cluster_dw_textblock { + style="dashed"; color="#000080"; fontname=Helvetica; fontsize=10; - Widget -> Textblock [arrowhead="none", arrowtail="empty", dir="both"]; - Textblock -> "Textblock::Word" [headlabel="*", taillabel="1"]; - Widget -> Table [arrowhead="none", arrowtail="empty", dir="both"]; - Table -> "Table::Row" [headlabel="*", taillabel="1"]; - Widget -> Image [arrowhead="none", arrowtail="empty", dir="both"]; + Textblock [URL="\ref dw::Textblock"]; + Word [URL="\ref dw::Textblock::Word"]; + WordImgRenderer [URL="\ref dw::Textblock::WordImgRenderer"]; + SpaceImgRenderer [URL="\ref dw::Textblock::SpaceImgRenderer"]; + } - BgAllocation -> Widget [arrowhead="none", arrowtail="empty", dir="both", - style="dashed"]; - BgAllocation -> "Textblock::Word" [arrowhead="none", arrowtail="empty", + Style -> StyleImage [headlabel="*", taillabel="1"]; + StyleImage -> Imgbuf [headlabel="*", taillabel="1"]; + StyleImage -> StyleImgRenderer [headlabel="1", taillabel="1"]; + StyleImage -> ImgRendererDist [headlabel="1", taillabel="1"]; + ImgRendererDist -> StyleImgRenderer [headlabel="1", taillabel="1"]; + ImgRendererDist -> ImgRenderer [headlabel="1", taillabel="*"]; + + ImgRenderer -> ImgRendererDist [arrowhead="none", arrowtail="empty", + dir="both", style="dashed"]; + ImgRenderer -> StyleImgRenderer [arrowhead="none", arrowtail="empty", + dir="both", style="dashed"]; + ImgRenderer -> ExternalImgRenderer [arrowhead="none", arrowtail="empty", dir="both", style="dashed"]; - BgAllocation -> "Table::Row" [arrowhead="none", arrowtail="empty", - dir="both", style="dashed"]; + ExternalImgRenderer -> ExternalWidgetImgRenderer [arrowhead="none", + arrowtail="empty", dir="both", style="dashed"]; + + Layout -> LayoutImgRenderer [headlabel="1", taillabel="0..1"]; + ExternalImgRenderer -> LayoutImgRenderer [arrowhead="none", + arrowtail="empty", dir="both", style="dashed"]; + + Widget -> WidgetImgRenderer [headlabel="1", taillabel="0..1"]; + ExternalWidgetImgRenderer -> WidgetImgRenderer [arrowhead="none", + arrowtail="empty", dir="both", style="dashed"]; + + Textblock -> Word [headlabel="1", taillabel="*"]; + Word -> WordImgRenderer [headlabel="1", taillabel="0..1"]; + Word -> SpaceImgRenderer [headlabel="1", taillabel="0..1"]; + ExternalWidgetImgRenderer -> WordImgRenderer [arrowhead="none", + arrowtail="empty", dir="both", style="dashed"]; + WordImgRenderer -> SpaceImgRenderer [arrowhead="none", arrowtail="empty", + dir="both", style="dashed"]; } \enddot <center>[\ref uml-legend "legend"]</center> -<h2>Integration into dillo</h2> - -\todo Add some references. +Memory management +----------------- +dw::core::style::StyleImage extends lout::signal::ObservedObject, so +that deleting this instance can be connected to code dealing with +cache clients etc. See StyleImageDeletionReceiver and how it is +attached in StyleEngine::apply ("case CSS_PROPERTY_BACKGROUND_IMAGE"). */ diff --git a/dw/imgrenderer.hh b/dw/imgrenderer.hh index 1efeef8c..e254ae66 100644 --- a/dw/imgrenderer.hh +++ b/dw/imgrenderer.hh @@ -18,7 +18,19 @@ class ImgRenderer public: virtual ~ImgRenderer () { } + /** + * \brief Called, when an image buffer is attached. + * + * This is typically the case when all meta data (size, depth) has been read. + */ virtual void setBuffer (core::Imgbuf *buffer, bool resize = false) = 0; + + /** + * \brief Called, when data from a row is available and has been copied into + * the image buffer. + * + * The implementation will typically queue the respective area for drawing. + */ virtual void drawRow (int row) = 0; }; |