Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hanging punctuation: new implementation #355

Merged
merged 1 commit into from
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion crengine/include/cssdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ enum css_generic_value_t {
// (it could have been a non-standard named value for line-height:, but we want to be
// able to not override existing line-height: values)
#define CSS_CR_HINT_STRUT_CONFINED 0x00000002 // -cr-hint: strut-confined (inheritable)
// Glyphs should not overflow line edges, and across text nodes or over images
// (it can also be used to disable hanging punctuation on the targeted nodes).
#define CSS_CR_HINT_FIT_GLYPHS 0x00000004 // -cr-hint: fit-glyphs (inheritable)

// A node with these should be considered as TOC item of level N when building alternate TOC
#define CSS_CR_HINT_TOC_LEVEL1 0x00000100 // -cr-hint: toc-level1
Expand Down Expand Up @@ -380,7 +383,7 @@ enum css_generic_value_t {
// everything else indicates it is)

// A few of them are inheritable, most are not.
#define CSS_CR_HINT_INHERITABLE_MASK 0x00000002
#define CSS_CR_HINT_INHERITABLE_MASK 0x00000006

// Macro for easier checking
#define STYLE_HAS_CR_HINT(s, h) ( (bool)(s->cr_hint.value & CSS_CR_HINT_##h) )
Expand Down
10 changes: 7 additions & 3 deletions crengine/include/lvrend.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class BlockFloatFootprint {
// Floats to transfer to final block for it to
// start with these 5 "fake" embedded floats
int floats_cnt;
int floats[5][5]; // max 5 floats, with (x,y,w,h,is_right) each
int floats[5][6]; // max 5 floats, with (x,y,w,h,is_right,inward_margin) each

int getFinalMinY() { return used_min_y; };
int getFinalMaxY() { return used_max_y; };
Expand Down Expand Up @@ -127,9 +127,11 @@ lUInt32 styleToTextFmtFlags( bool is_block, const css_style_ref_t & style, lUInt
void renderFinalBlock( ldomNode * node, LFormattedText * txform, RenderRectAccessor * fmt, lUInt32 & flags,
int indent, int line_h, TextLangCfg * lang_cfg=NULL, int valign_dy=0, bool * is_link_start=NULL );
/// renders block which contains subblocks (with gRenderBlockRenderingFlags as flags)
int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, int y, int width, int direction=REND_DIRECTION_UNSET, int * baseline=NULL );
int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, int y, int width,
int usable_left_overflow=0, int usable_right_overflow=0, int direction=REND_DIRECTION_UNSET, int * baseline=NULL );
/// renders block which contains subblocks
int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, int y, int width, int direction, int * baseline, int rend_flags );
int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, int y, int width,
int usable_left_overflow, int usable_right_overflow, int direction, int * baseline, int rend_flags );
/// renders table element
int renderTable( LVRendPageContext & context, ldomNode * element, int x, int y, int width,
bool shrink_to_fit, int & fitted_width, int direction=REND_DIRECTION_UNSET,
Expand Down Expand Up @@ -173,6 +175,8 @@ extern int gRenderDPI;
extern bool gRenderScaleFontWithDPI;
extern int gRootFontSize;

extern bool gHangingPunctuationEnabled;

#define INTERLINE_SCALE_FACTOR_NO_SCALE 1024
#define INTERLINE_SCALE_FACTOR_SHIFT 10
extern int gInterlineScaleFactor;
Expand Down
20 changes: 12 additions & 8 deletions crengine/include/lvstyles.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ class lvdomElementFormatRec {
// is also limited to that for being carried in lInt16 slots when
// formatting text in lvtextfm.cpp.)

short _usable_left_overflow; // Usable overflow for hanging punctuation
short _usable_right_overflow; // and glyphs negative side bearings

// Children blocks should be fully contained in their parent block,
// and sibling nodes blocks should not overlap with other siblings,
// except when float are involved and we allow them to continue
Expand Down Expand Up @@ -351,18 +354,19 @@ class lvdomElementFormatRec {
int _listprop_node_idx; // dataIndex of the UL/OL node this erm_final block
// should get its marker from

// Added for padding from 15 to 16 32-bits ints
int _available1;
// We're now at 16 32-bits ints. If needing new fields, add some padding:
// Added for padding from 17 to 20 32-bits ints
// int _available1; int _available2; int _available3;

public:
lvdomElementFormatRec()
: _x(0), _width(0), _y(0), _height(0)
, _inner_width(0), _inner_x(0), _inner_y(0), _baseline(0)
, _usable_left_overflow(0), _usable_right_overflow(0)
, _top_overflow(0), _bottom_overflow(0)
, _lang_node_idx(0) , _listprop_node_idx(0)
, _flags(0), _extra0(0)
, _extra1(0), _extra2(0), _extra3(0), _extra4(0), _extra5(0)
, _available1(0)
{
}
~lvdomElementFormatRec()
Expand All @@ -372,36 +376,36 @@ class lvdomElementFormatRec {
{
_x = _width = _y = _height = 0;
_inner_width = _inner_x = _inner_y = _baseline = 0;
_usable_left_overflow = _usable_right_overflow = 0;
_top_overflow = _bottom_overflow = 0;
_lang_node_idx = _listprop_node_idx = 0;
_flags = _extra0 = 0;
_extra1 = _extra2 = _extra3 = _extra4 = _extra5 = 0;
_available1 = 0;
}
bool operator == ( lvdomElementFormatRec & v )
{
return (_height==v._height && _y==v._y && _width==v._width && _x==v._x &&
_inner_width==v._inner_width && _inner_x==v._inner_x &&
_inner_y==v._inner_y && _baseline==v._baseline &&
_usable_left_overflow==v._usable_left_overflow && _usable_right_overflow==v._usable_right_overflow &&
_top_overflow==v._top_overflow && _bottom_overflow==v._bottom_overflow &&
_lang_node_idx==v._lang_node_idx && _listprop_node_idx==v._listprop_node_idx &&
_flags==v._flags && _extra0==v._extra0 &&
_extra1==v._extra1 && _extra2==v._extra2 && _extra3==v._extra3 &&
_extra4==v._extra4 && _extra5==v._extra5 &&
_available1==v._available1
_extra4==v._extra4 && _extra5==v._extra5
);
}
bool operator != ( lvdomElementFormatRec & v )
{
return (_height!=v._height || _y!=v._y || _width!=v._width || _x!=v._x ||
_inner_width!=v._inner_width || _inner_x!=v._inner_x ||
_inner_y!=v._inner_y || _baseline!=v._baseline ||
_usable_left_overflow!=v._usable_left_overflow || _usable_right_overflow!=v._usable_right_overflow ||
_top_overflow!=v._top_overflow || _bottom_overflow!=v._bottom_overflow ||
_lang_node_idx!=v._lang_node_idx || _listprop_node_idx!=v._listprop_node_idx ||
_flags!=v._flags || _extra0!=v._extra0 ||
_extra1!=v._extra1 || _extra2!=v._extra2 || _extra3!=v._extra3 ||
_extra4!=v._extra4 || _extra5!=v._extra5 ||
_available1!=v._available1
_extra4!=v._extra4 || _extra5!=v._extra5
);
}
// Get/Set
Expand Down
13 changes: 6 additions & 7 deletions crengine/include/lvtextfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
#include "lvbmpbuf.h"
#include "textlang.h"

// comment out following line to use old formatter
#define USE_NEW_FORMATTER 1

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -81,7 +78,8 @@ extern "C" {
#define LTEXT_SRC_IS_CLEAR_BOTH 0x03000000 // text follows <BR style="clear: both">
#define LTEXT_SRC_IS_CLEAR_LAST 0x04000000 // ignorable text, added when nothing follows <BR style="clear: both">

#define LTEXT__AVAILABLE_BIT_28__ 0x08000000
#define LTEXT_FIT_GLYPHS 0x08000000 // Avoid glyph overflows and override at line edges and between text nodes

#define LTEXT__AVAILABLE_BIT_29__ 0x10000000
#define LTEXT__AVAILABLE_BIT_30__ 0x20000000
#define LTEXT__AVAILABLE_BIT_31__ 0x40000000
Expand Down Expand Up @@ -212,7 +210,8 @@ typedef struct
lInt32 y; /**< start y position of float */
lInt16 x; /**< start x position */
lUInt16 width; /**< width */
lUInt16 height; /**< height */
lUInt32 height; /**< height */
lUInt16 inward_margin; /**< inward margin */
css_clear_t clear; /**< clear: css property value */
bool is_right; /**< is float: right */
bool to_position; /**< not yet positionned */
Expand Down Expand Up @@ -432,6 +431,8 @@ class LFormattedText

lUInt32 Format(lUInt16 width, lUInt16 page_height,
int para_direction=0, // = REND_DIRECTION_UNSET in lvrend.h
int usable_left_overflow=0, int usable_right_overflow=0,
bool hanging_punctuation=false,
BlockFloatFootprint * float_footprint = NULL );

int GetSrcCount()
Expand Down Expand Up @@ -481,6 +482,4 @@ class LFormattedText

#endif

extern bool gFlgFloatingPunctuationEnabled;

#endif
12 changes: 10 additions & 2 deletions crengine/include/lvtinydom.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,11 @@ class RenderRectAccessor : public lvdomElementFormatRec
void setInnerY( int y );
void setInnerWidth( int w );

int getUsableLeftOverflow();
int getUsableRightOverflow();
void setUsableLeftOverflow( int dx );
void setUsableRightOverflow( int dx );

int getTopOverflow();
int getBottomOverflow();
void setTopOverflow( int dy );
Expand Down Expand Up @@ -2514,9 +2519,12 @@ class ldomDocument : public lxmlDocBase
#if BUILD_LITE!=1
bool isRendered() { return _rendered; }
/// renders (formats) document in memory: returns true if re-rendering needed, false if not
virtual bool render( LVRendPageList * pages, LVDocViewCallback * callback, int width, int dy, bool showCover, int y0, font_ref_t def_font, int def_interline_space, CRPropRef props );
virtual bool render( LVRendPageList * pages, LVDocViewCallback * callback, int width, int dy,
bool showCover, int y0, font_ref_t def_font, int def_interline_space,
CRPropRef props, int usable_left_overflow=0, int usable_right_overflow=0 );
/// set global rendering properties
virtual bool setRenderProps( int width, int dy, bool showCover, int y0, font_ref_t def_font, int def_interline_space, CRPropRef props );
virtual bool setRenderProps( int width, int dy, bool showCover, int y0, font_ref_t def_font,
int def_interline_space, CRPropRef props );
#endif
/// create xpointer from pointer string
ldomXPointer createXPointer( const lString16 & xPointerStr );
Expand Down
3 changes: 3 additions & 0 deletions crengine/include/textlang.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ class TextLangCfg
lString16 & getOpeningQuote( bool update_level=true );
lString16 & getClosingQuote( bool update_level=true );

int getHyphenHangingPercent();
int getHangingPercent( bool right_hanging, bool & check_font, const lChar16 * text, int pos, int next_usable );

#if USE_HARFBUZZ==1
hb_language_t getHBLanguage() const { return _hb_language; }
#endif
Expand Down
17 changes: 11 additions & 6 deletions crengine/src/lvdocview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2779,7 +2779,8 @@ void LVDocView::Render(int dx, int dy, LVRendPageList * pages) {
//CRLog::trace("calling render() for document %08X font=%08X", (unsigned int)m_doc, (unsigned int)m_font.get() );
bool did_rerender = m_doc->render(pages, isDocumentOpened() ? m_callback : NULL, dx, dy,
m_showCover, m_showCover ? dy + m_pageMargins.bottom * 4 : 0,
m_font, m_def_interline_space, m_props);
m_font, m_def_interline_space, m_props,
m_pageMargins.left, m_pageMargins.right);

#if 0
// For debugging lvpagesplitter.cpp (small books)
Expand Down Expand Up @@ -6244,7 +6245,9 @@ CRPropRef LVDocView::propsApply(CRPropRef props) {
if ((int)fontMan->GetHintingMode() != mode && mode>=0 && mode<=2) {
//CRLog::debug("Setting hinting mode to %d", mode);
fontMan->SetHintingMode((hinting_mode_t)mode);
requestRender(); // does m_doc->clearRendBlockCache(), which is needed on hinting mode change
REQUEST_RENDER("propsApply - font hinting")
// requestRender() does m_doc->clearRendBlockCache(), which is needed
// on hinting mode change
}
} else if (name == PROP_HIGHLIGHT_SELECTION_COLOR || name == PROP_HIGHLIGHT_BOOKMARK_COLOR_COMMENT || name == PROP_HIGHLIGHT_BOOKMARK_COLOR_COMMENT) {
REQUEST_RENDER("propsApply - highlight")
Expand All @@ -6260,7 +6263,7 @@ CRPropRef LVDocView::propsApply(CRPropRef props) {
if ((int)fontMan->GetKerningMode() != mode && mode>=0 && mode<=3) {
//CRLog::debug("Setting kerning mode to %d", mode);
fontMan->SetKerningMode((kerning_mode_t)mode);
requestRender();
REQUEST_RENDER("propsApply - font kerning")
}
} else if (name == PROP_FONT_WEIGHT_EMBOLDEN) {
bool embolden = props->getBoolDef(PROP_FONT_WEIGHT_EMBOLDEN, false);
Expand Down Expand Up @@ -6463,9 +6466,11 @@ CRPropRef LVDocView::propsApply(CRPropRef props) {
REQUEST_RENDER("propsApply footnotes")
} else if (name == PROP_FLOATING_PUNCTUATION) {
bool value = props->getBoolDef(PROP_FLOATING_PUNCTUATION, true);
if ( gFlgFloatingPunctuationEnabled != value ) {
gFlgFloatingPunctuationEnabled = value;
REQUEST_RENDER("propsApply floating punct")
if ( gHangingPunctuationEnabled != value ) {
gHangingPunctuationEnabled = value;
REQUEST_RENDER("propsApply - hanging punctuation")
// requestRender() does m_doc->clearRendBlockCache(), which is needed
// on hanging punctuation change
}
} else if (name == PROP_RENDER_BLOCK_RENDERING_FLAGS) {
int value = props->getIntDef(PROP_RENDER_BLOCK_RENDERING_FLAGS, DEF_RENDER_BLOCK_RENDERING_FLAGS);
Expand Down
Loading