1 /** \file lvrend.h 2 \brief DOM document rendering (formatting) functions 3 4 CoolReader Engine 5 6 (c) Vadim Lopatin, 2000-2006 7 This source code is distributed under the terms of 8 GNU General Public License. 9 10 See LICENSE file for details. 11 12 */ 13 14 #ifndef __LV_REND_H_INCLUDED__ 15 #define __LV_REND_H_INCLUDED__ 16 17 #include "lvtinydom.h" 18 #include "textlang.h" 19 20 // Current direction, from dir="ltr" or dir="rtl" element attribute 21 // Should map directly to the RENDER_RECT_FLAG_DIRECTION_* below 22 // (bit 0: 0=unset 1=set - bit 1: 0=normal 1=inverted - bit 2: 0=horizontal 1=vertical) 23 #define REND_DIRECTION_UNSET 0X00 24 #define REND_DIRECTION_LTR 0X01 // 0b001 25 #define REND_DIRECTION_RTL 0X03 // 0b011 26 // Not supported: 27 // #define REND_DIRECTION_TTB 0X05 // 0b101 28 // #define REND_DIRECTION_BTT 0X07 // 0b111 29 30 // Flags for RenderRectAccessor 31 #define RENDER_RECT_FLAG_DIRECTION_SET 0x0001 32 #define RENDER_RECT_FLAG_DIRECTION_INVERTED 0x0002 33 #define RENDER_RECT_FLAG_DIRECTION_VERTICAL 0x0004 // not used (only horizontal currently supported) 34 #define RENDER_RECT_FLAG_INNER_FIELDS_SET 0x0008 35 #define RENDER_RECT_FLAG_BOX_IS_RENDERED 0x0010 // for floatBox and inlineBox 36 #define RENDER_RECT_FLAG_NO_CLEAR_OWN_FLOATS 0x0020 37 #define RENDER_RECT_FLAG_FINAL_FOOTPRINT_AS_SAVED_FLOAT_IDS 0x0040 38 #define RENDER_RECT_FLAG_FLOATBOX_IS_RIGHT 0x0080 39 #define RENDER_RECT_FLAG_NO_INTERLINE_SCALE_UP 0x0100 // for ruby elements to not scale up 40 #define RENDER_RECT_FLAG_CHILDREN_RENDERING_REORDERED 0x0200 // for table rows/thead/tfoot reordering 41 #define RENDER_RECT_FLAG_TEMP_USED_AS_CSS_CHECK_CACHE 0x8000 // has been cleared and is used as a CSS checks cache 42 43 #define RENDER_RECT_SET_FLAG(r, f) ( r.setFlags( r.getFlags() | RENDER_RECT_FLAG_##f ) ) 44 #define RENDER_RECT_UNSET_FLAG(r, f) ( r.setFlags( r.getFlags() & ~RENDER_RECT_FLAG_##f ) ) 45 #define RENDER_RECT_HAS_FLAG(r, f) ( (bool)(r.getFlags() & RENDER_RECT_FLAG_##f) ) 46 #define RENDER_RECT_PTR_HAS_FLAG(r, f) ( (bool)(r->getFlags() & RENDER_RECT_FLAG_##f) ) 47 48 #define RENDER_RECT_FLAG_DIRECTION_MASK 0x0007 49 #define RENDER_RECT_SET_DIRECTION(r, d) ( r.setFlags( r.getFlags() | d ) ) 50 #define RENDER_RECT_GET_DIRECTION(r) ( r.getFlags() & RENDER_RECT_FLAG_DIRECTION_MASK ) 51 #define RENDER_RECT_PTR_GET_DIRECTION(r) ( r->getFlags() & RENDER_RECT_FLAG_DIRECTION_MASK ) 52 #define RENDER_RECT_HAS_DIRECTION(r) ( (bool)(r.getFlags() & RENDER_RECT_FLAG_DIRECTION_SET) ) 53 #define RENDER_RECT_HAS_DIRECTION_RTL(r) ( (bool)(r.getFlags() & RENDER_RECT_FLAG_DIRECTION_MASK == REND_DIRECTION_RTL) ) 54 #define RENDER_RECT_PTR_HAS_DIRECTION_RTL(r) ( (bool)(r->getFlags() & RENDER_RECT_FLAG_DIRECTION_MASK == REND_DIRECTION_RTL) ) 55 56 // To be provided via the initial value to renderBlockElement(... int *baseline ...) to 57 // have FlowState compute baseline (different rules whether inline-block or inline-table). 58 #define REQ_BASELINE_NOT_NEEDED 0 59 #define REQ_BASELINE_FOR_INLINE_BLOCK 1 // use last baseline fed 60 #define REQ_BASELINE_FOR_TABLE 2 // keep first baseline fed 61 62 class FlowState; 63 64 // Footprint of block floats (from FlowState) on a final block, 65 // to be passed to lvtextfm LFormattedText::Format(). 66 // Also allows LFormattedText to pass back information about 67 // its own embedded floats if they overflow the final block 68 // own height. 69 class BlockFloatFootprint { 70 private: 71 FlowState * flow; 72 int d_left; 73 int d_top; 74 int used_min_y; 75 int used_max_y; 76 public: 77 // Forwarded from BLOCK_RENDERING_DO_NOT_CLEAR_OWN_FLOATS 78 // (or not when table cell erm_final) 79 bool no_clear_own_floats; 80 bool use_floatIds; 81 // Footprints, used when they are more than 5 floats involved, 82 // or ALLOW_EXACT_FLOATS_FOOTPRINTS not enabled. 83 int left_w; 84 int left_h; 85 int right_w; 86 int right_h; 87 int left_min_y; 88 int right_min_y; 89 // FloatIds, used when less than 5 floats involved 90 // and ALLOW_EXACT_FLOATS_FOOTPRINTS enabled 91 int nb_floatIds; 92 lUInt32 floatIds[5]; 93 // Floats to transfer to final block for it to 94 // start with these 5 "fake" embedded floats 95 int floats_cnt; 96 int floats[5][6]; // max 5 floats, with (x,y,w,h,is_right,inward_margin) each 97 getFinalMinY()98 int getFinalMinY() { return used_min_y; }; getFinalMaxY()99 int getFinalMaxY() { return used_max_y; }; 100 void store( ldomNode * node ); 101 void restore( ldomNode * node, int final_width ); 102 void generateEmbeddedFloatsFromFootprints( int final_width ); 103 void generateEmbeddedFloatsFromFloatIds( ldomNode * node, int final_width ); 104 void forwardOverflowingFloat( int x, int y, int w, int h, bool r, ldomNode * node ); 105 int getTopShiftX(int final_width, bool get_right_shift=false); 106 107 BlockFloatFootprint( FlowState * fl=NULL, int dleft=0, int dtop=0, bool noclearownfloats=false ) : flow(fl)108 flow(fl), d_left(dleft), d_top(dtop), no_clear_own_floats(noclearownfloats), 109 used_min_y(0), used_max_y(0), 110 left_w(0), left_h(0), right_w(0), right_h(0), left_min_y(0), right_min_y(0), 111 use_floatIds(false), nb_floatIds(0), floats_cnt(0) 112 { } 113 }; 114 115 /// returns true if styles are identical 116 bool isSameFontStyle( css_style_rec_t * style1, css_style_rec_t * style2 ); 117 /// removes format data from node 118 void freeFormatData( ldomNode * node ); 119 /// returns best suitable font for style 120 LVFontRef getFont(css_style_rec_t * style, int documentId); 121 /// initializes format data for node 122 void initFormatData( ldomNode * node ); 123 /// initializes rendering method for node 124 int initRendMethod( ldomNode * node, bool recurseChildren, bool allowAutoboxing ); 125 /// converts style to text formatting API flags 126 lUInt32 styleToTextFmtFlags( bool is_block, const css_style_ref_t & style, lUInt32 oldflags, int direction=REND_DIRECTION_UNSET ); 127 /// renders block as single text formatter object 128 void renderFinalBlock( ldomNode * node, LFormattedText * txform, RenderRectAccessor * fmt, lUInt32 & flags, 129 int indent, int line_h, TextLangCfg * lang_cfg=NULL, int valign_dy=0, bool * is_link_start=NULL ); 130 /// renders block which contains subblocks (with enode document's rendering flags) 131 int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, int y, int width, 132 int usable_left_overflow=0, int usable_right_overflow=0, int direction=REND_DIRECTION_UNSET, int * baseline=NULL ); 133 /// renders block which contains subblocks 134 int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, int y, int width, 135 int usable_left_overflow, int usable_right_overflow, int direction, int * baseline, lUInt32 rend_flags ); 136 /// renders table element 137 int renderTable( LVRendPageContext & context, ldomNode * element, int x, int y, int width, 138 bool shrink_to_fit, int & fitted_width, int direction=REND_DIRECTION_UNSET, 139 bool pb_inside_avoid=false, bool enhanced_rendering=false, bool is_ruby_table=false ); 140 /// sets node style 141 void setNodeStyle( ldomNode * node, css_style_ref_t parent_style, LVFontRef parent_font ); 142 /// copy style 143 void copystyle( css_style_ref_t sourcestyle, css_style_ref_t deststyle ); 144 145 /// draws formatted document to drawing buffer 146 void DrawDocument( LVDrawBuf & drawbuf, ldomNode * node, int x0, int y0, int dx, int dy, int doc_x, int doc_y, 147 int page_height, ldomMarkedRangeList * marks, ldomMarkedRangeList * bookmarks = NULL, 148 bool draw_content=true, bool draw_background=true ); 149 150 // Estimate width of node when rendered: 151 // maxWidth: width if it would be rendered on an infinite width area 152 // minWidth: width with a wrap on all spaces (no hyphenation), so width taken by the longest word 153 // full function for recursive use: 154 void getRenderedWidths(ldomNode * node, int &maxWidth, int &minWidth, int direction, bool ignorePadding, int rendFlags, 155 int &curMaxWidth, int &curWordWidth, bool &collapseNextSpace, int &lastSpaceWidth, 156 int indent, TextLangCfg * lang_cfg, bool processNodeAsText=false, bool isStartNode=false); 157 // simpler function for first call: 158 void getRenderedWidths(ldomNode * node, int &maxWidth, int &minWidth, int direction=REND_DIRECTION_UNSET, bool ignorePadding=false, int rendFlags=0); 159 160 #define STYLE_FONT_EMBOLD_MODE_NORMAL 0 161 #define STYLE_FONT_EMBOLD_MODE_EMBOLD 300 162 163 /// set global document font style embolden mode (0=off, 300=on) 164 void LVRendSetFontEmbolden( int addWidth=STYLE_FONT_EMBOLD_MODE_EMBOLD ); 165 /// get global document font style embolden mode 166 int LVRendGetFontEmbolden(); 167 168 int measureBorder(ldomNode *enode,int border); 169 int lengthToPx( css_length_t val, int base_px, int base_em, bool unspecified_as_em=false ); 170 int scaleForRenderDPI( int value ); 171 172 #define BASE_CSS_DPI 96 // at 96 dpi, 1 css px = 1 screen px 173 #define DEF_RENDER_DPI 96 174 #define DEF_RENDER_SCALE_FONT_WITH_DPI 0 175 extern int gRenderDPI; 176 extern bool gRenderScaleFontWithDPI; 177 extern int gRootFontSize; 178 179 #define INTERLINE_SCALE_FACTOR_NO_SCALE 1024 180 #define INTERLINE_SCALE_FACTOR_SHIFT 10 181 182 // Enhanced rendering flags 183 #define BLOCK_RENDERING_ENHANCED 0x00000001 184 #define BLOCK_RENDERING_ALLOW_PAGE_BREAK_WHEN_NO_CONTENT 0x00000002 // Allow consecutive page breaks when only separated 185 // by margin/padding/border. 186 // Vertical margins 187 #define BLOCK_RENDERING_COLLAPSE_VERTICAL_MARGINS 0x00000010 // Collapse vertical margins 188 #define BLOCK_RENDERING_ALLOW_VERTICAL_NEGATIVE_MARGINS 0x00000020 // Allow individual negative margins in the calculation, the 189 // final collapsed margin is ensure to be zero or positive. 190 #define BLOCK_RENDERING_ALLOW_NEGATIVE_COLLAPSED_MARGINS 0x00000040 // Allow the final vertical collapsed margin to be negative 191 // (may mess with page splitting and text selection). 192 // Horizontal margins 193 #define BLOCK_RENDERING_ENSURE_MARGIN_AUTO_ALIGNMENT 0x00000100 // Ensure CSS "margin: auto", for aligning blocks. 194 #define BLOCK_RENDERING_ALLOW_HORIZONTAL_NEGATIVE_MARGINS 0x00000200 // Allow negative margins (otherwise, they are set to 0) 195 #define BLOCK_RENDERING_ALLOW_HORIZONTAL_BLOCK_OVERFLOW 0x00000400 // Allow block content to overflow its block container. 196 #define BLOCK_RENDERING_ALLOW_HORIZONTAL_PAGE_OVERFLOW 0x00000800 // Allow block content to overflow the page rect, showing 197 // in the margin, and possibly clipped out. 198 // Widths and heights 199 #define BLOCK_RENDERING_USE_W3C_BOX_MODEL 0x00001000 // Use W3C box model (CSS width and height do not include 200 // paddings and borders) 201 #define BLOCK_RENDERING_ALLOW_STYLE_W_H_ABSOLUTE_UNITS 0x00002000 // Allow widths and heights in absolute units (when ensured) 202 #define BLOCK_RENDERING_ENSURE_STYLE_WIDTH 0x00004000 // Ensure CSS widths and heights on all elements (otherwise 203 #define BLOCK_RENDERING_ENSURE_STYLE_HEIGHT 0x00008000 // only on <HR> and images, and when sizing floats). 204 // Floats 205 #define BLOCK_RENDERING_WRAP_FLOATS 0x00010000 // Wrap floats in an internal floatBox element. 206 #define BLOCK_RENDERING_PREPARE_FLOATBOXES 0x00020000 // Avoid style hash mismatch when toggling FLOAT_FLOATBOXES, 207 // but make embedded floats inline when no more floating. 208 #define BLOCK_RENDERING_FLOAT_FLOATBOXES 0x00040000 // Actually render floatBoxes floating. 209 // These 2, although allowing a more correct rendering of floats, can impact drawing performances and text/links selection: 210 #define BLOCK_RENDERING_DO_NOT_CLEAR_OWN_FLOATS 0x00100000 // Prevent blocks from clearing their own floats. 211 #define BLOCK_RENDERING_ALLOW_EXACT_FLOATS_FOOTPRINTS 0x00200000 // When 5 or less outer floats have impact on a final 212 // block, store their ids instead of the 2 top left/right 213 // rectangle, allowing text layout staircase-like. 214 // Inline block/table 215 #define BLOCK_RENDERING_BOX_INLINE_BLOCKS 0x01000000 // Wrap inline-block in an internal inlineBox element. 216 #define BLOCK_RENDERING_COMPLETE_INCOMPLETE_TABLES 0x02000000 // Add anonymous missing elements to a table without proper 217 // children and table-cells without proper parents 218 219 // Enable everything 220 #define BLOCK_RENDERING_FULL_FEATURED 0x7FFFFFFF 221 222 // Some macros (for shorter lines of code) 223 #define BLOCK_RENDERING(v, f) ((bool)( v & BLOCK_RENDERING_##f )) 224 #define BLOCK_RENDERING_D(d, f) ((bool)( d->getRenderBlockRenderingFlags() & BLOCK_RENDERING_##f )) 225 #define BLOCK_RENDERING_N(n, f) ((bool)( n->getDocument()->getRenderBlockRenderingFlags() & BLOCK_RENDERING_##f )) 226 227 // rendering flags presets 228 #define BLOCK_RENDERING_FLAGS_LEGACY 0 229 #define BLOCK_RENDERING_FLAGS_FLAT ( BLOCK_RENDERING_ENHANCED | \ 230 BLOCK_RENDERING_COLLAPSE_VERTICAL_MARGINS | \ 231 BLOCK_RENDERING_ALLOW_VERTICAL_NEGATIVE_MARGINS | \ 232 BLOCK_RENDERING_USE_W3C_BOX_MODEL | \ 233 BLOCK_RENDERING_WRAP_FLOATS | \ 234 BLOCK_RENDERING_PREPARE_FLOATBOXES | \ 235 BLOCK_RENDERING_BOX_INLINE_BLOCKS ) 236 #define BLOCK_RENDERING_FLAGS_BOOK ( BLOCK_RENDERING_ENHANCED | \ 237 BLOCK_RENDERING_COLLAPSE_VERTICAL_MARGINS | \ 238 BLOCK_RENDERING_ALLOW_VERTICAL_NEGATIVE_MARGINS | \ 239 BLOCK_RENDERING_ENSURE_MARGIN_AUTO_ALIGNMENT | \ 240 BLOCK_RENDERING_USE_W3C_BOX_MODEL | \ 241 BLOCK_RENDERING_ENSURE_STYLE_WIDTH | \ 242 BLOCK_RENDERING_WRAP_FLOATS | \ 243 BLOCK_RENDERING_PREPARE_FLOATBOXES | \ 244 BLOCK_RENDERING_FLOAT_FLOATBOXES | \ 245 BLOCK_RENDERING_DO_NOT_CLEAR_OWN_FLOATS | \ 246 BLOCK_RENDERING_ALLOW_EXACT_FLOATS_FOOTPRINTS | \ 247 BLOCK_RENDERING_BOX_INLINE_BLOCKS ) 248 #define BLOCK_RENDERING_FLAGS_WEB BLOCK_RENDERING_FULL_FEATURED 249 #define BLOCK_RENDERING_FLAGS_DEFAULT BLOCK_RENDERING_FLAGS_WEB 250 251 #endif 252