summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/hyphenator.cc13
-rw-r--r--dw/hyphenator.hh1
-rw-r--r--dw/textblock.cc55
-rw-r--r--dw/textblock.hh12
-rw-r--r--dw/textblock_linebreaking.cc24
5 files changed, 63 insertions, 42 deletions
diff --git a/dw/hyphenator.cc b/dw/hyphenator.cc
index 8f73bc80..998b7975 100644
--- a/dw/hyphenator.cc
+++ b/dw/hyphenator.cc
@@ -117,6 +117,16 @@ void Hyphenator::insertPattern (char *s)
}
/**
+ * Simple test to avoid much costs. Passing it does not mean that the word
+ * can be hyphenated.
+ */
+bool Hyphenator::isHyphenationCandidate (const char *word)
+{
+ // Short words aren't hyphenated.
+ return (strlen (word) > 4); // TODO UTF-8?
+}
+
+/**
* Given a word, returns a list of pieces, broken at the possible
* hyphenation points.
*/
@@ -124,8 +134,7 @@ Vector <String> *Hyphenator::hyphenateWord(const char *word)
{
Vector <String> *pieces = new Vector <String> (1, true);
- // Short words aren't hyphenated.
- if (strlen (word) <= 4) { // TODO UTF-8?
+ if (!isHyphenationCandidate (word) <= 4) {
pieces->put (new String (word));
return pieces;
}
diff --git a/dw/hyphenator.hh b/dw/hyphenator.hh
index 97de965f..839f6cc9 100644
--- a/dw/hyphenator.hh
+++ b/dw/hyphenator.hh
@@ -32,6 +32,7 @@ public:
static Hyphenator *getHyphenator (core::Platform *platform,
const char *language);
+ static bool isHyphenationCandidate (const char *word);
lout::container::typed::Vector <lout::object::String>
*hyphenateWord(const char *word);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 826b6648..b4a2b66c 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -1223,13 +1223,18 @@ void Textblock::draw (core::View *view, core::Rectangle *area)
* Add a new word (text, widget etc.) to a page.
*/
Textblock::Word *Textblock::addWord (int width, int ascent, int descent,
+ bool canBeHyphenated,
core::style::Style *style)
{
- Word *word;
-
words->increase ();
+ Word *word = words->getLastRef ();
+ fillWord (word, width, ascent, descent, canBeHyphenated, style);
+ return word;
+}
- word = words->getRef (words->size() - 1);
+void Textblock::fillWord (Word *word, int width, int ascent, int descent,
+ bool canBeHyphenated, core::style::Style *style)
+{
word->size.width = width;
word->size.ascent = ascent;
word->size.descent = descent;
@@ -1238,19 +1243,7 @@ Textblock::Word *Textblock::addWord (int width, int ascent, int descent,
word->hyphenWidth = 0;
word->badnessAndPenalty.setPenaltyProhibitBreak ();
word->content.space = false;
-
- //DBG_OBJ_ARRSET_NUM (this, "words.%d.size.width", words->size() - 1,
- // word->size.width);
- //DBG_OBJ_ARRSET_NUM (this, "words.%d.size.descent", words->size() - 1,
- // word->size.descent);
- //DBG_OBJ_ARRSET_NUM (this, "words.%d.size.ascent", words->size() - 1,
- // word->size.ascent);
- //DBG_OBJ_ARRSET_NUM (this, "words.%d.orig_space", words->size() - 1,
- // word->orig_space);
- //DBG_OBJ_ARRSET_NUM (this, "words.%d.effSpace", words->size() - 1,
- // word->eff_space);
- //DBG_OBJ_ARRSET_NUM (this, "words.%d.content.space", words->size() - 1,
- // word->content.space);
+ word->canBeHyphenated = canBeHyphenated;
word->style = style;
word->spaceStyle = style;
@@ -1258,8 +1251,6 @@ Textblock::Word *Textblock::addWord (int width, int ascent, int descent,
style->ref ();
style->ref ();
style->ref ();
-
- return word;
}
/*
@@ -1387,10 +1378,11 @@ void Textblock::addText (const char *text, size_t len,
numHyphens++;
if (numHyphens == 0) {
- // Simple (and often) case: no soft hyphens.
+ // Simple (and often) case: no soft hyphens. May still be hyphenated
+ // automatically.
core::Requisition size;
calcTextSize (text, len, style, &size);
- addText0 (text, len, style, &size);
+ addText0 (text, len, true, style, &size);
} else {
PRINTF("HYPHENATION: '");
for (size_t i = 0; i < len; i++)
@@ -1454,7 +1446,8 @@ void Textblock::addText (const char *text, size_t len,
for (int i = 0; i < numHyphens + 1; i++) {
int start = (i == 0) ? 0 : hyphenPos[i - 1] + 2;
int end = (i == numHyphens) ? len : hyphenPos[i];
- addText0 (text + start, end - start, style, &wordSize[i]);
+ // Do not anymore hyphen automatically.
+ addText0 (text + start, end - start, false, style, &wordSize[i]);
PRINTF("H... [%d] '", i);
for (int j = start; j < end; j++)
@@ -1469,21 +1462,18 @@ void Textblock::addText (const char *text, size_t len,
}
}
+
/**
* Add a word (without hyphens) to the page structure.
*/
-void Textblock::addText0 (const char *text, size_t len,
+void Textblock::addText0 (const char *text, size_t len, bool canBeHyphenated,
core::style::Style *style, core::Requisition *size)
{
- Word *word;
-
- word = addWord (size->width, size->ascent, size->descent, style);
+ Word *word = addWord (size->width, size->ascent, size->descent,
+ canBeHyphenated, style);
word->content.type = core::Content::TEXT;
word->content.text = layout->textZone->strndup(text, len);
- //DBG_OBJ_ARRSET_STR (page, "words.%d.content.text", words->size() - 1,
- // word->content.text);
-
wordWrap (words->size () - 1, false);
}
@@ -1507,7 +1497,7 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
widget->setStyle (style);
calcWidgetSize (widget, &size);
- word = addWord (size.width, size.ascent, size.descent, style);
+ word = addWord (size.width, size.ascent, size.descent, false, style);
word->content.type = core::Content::WIDGET;
word->content.widget = widget;
@@ -1700,7 +1690,7 @@ void Textblock::addParbreak (int space, core::style::Style *style)
return;
}
- word = addWord (0, 0, 0, style);
+ word = addWord (0, 0, 0, false, style);
word->content.type = core::Content::BREAK;
word->badnessAndPenalty.setPenaltyForceBreak ();
word->content.breakSpace = space;
@@ -1718,10 +1708,11 @@ void Textblock::addLinebreak (core::style::Style *style)
words->getRef(words->size () - 1)->content.type == core::Content::BREAK)
// An <BR> in an empty line gets the height of the current font
// (why would someone else place it here?), ...
- word = addWord (0, style->font->ascent, style->font->descent, style);
+ word =
+ addWord (0, style->font->ascent, style->font->descent, false, style);
else
// ... otherwise, it has no size (and does not enlarge the line).
- word = addWord (0, 0, 0, style);
+ word = addWord (0, 0, 0, false, style);
word->content.type = core::Content::BREAK;
word->badnessAndPenalty.setPenaltyForceBreak ();
diff --git a/dw/textblock.hh b/dw/textblock.hh
index b301db7d..778d5b35 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -156,6 +156,7 @@ private:
private:
enum { TOO_LOOSE, TOO_TIGHT, BADNESS_VALUE } badnessState;
enum { FORCE_BREAK, PROHIBIT_BREAK, PENALTY_VALUE } penaltyState;
+ int ratio; // ratio is only defined when badness is defined
int badness, penalty;
// for debugging:
@@ -173,6 +174,8 @@ private:
void setPenaltyProhibitBreak ();
void setPenaltyForceBreak ();
+ bool lineLoose ();
+ bool lineTight ();
bool lineTooTight ();
bool lineMustBeBroken ();
bool lineCanBeBroken ();
@@ -227,6 +230,7 @@ protected:
* "hyphenWidth > 0" is also used to decide
* weather to draw a hyphen. */
core::Content content;
+ bool canBeHyphenated;
// accumulated values, relative to the beginning of the line
int totalWidth; /* The sum of all word widths; plus all
@@ -356,8 +360,10 @@ protected:
int findLineOfWord (int wordIndex);
Word *findWord (int x, int y, bool *inSpace);
- Word *addWord (int width, int ascent, int descent,
+ Word *addWord (int width, int ascent, int descent, bool canBeHyphenated,
core::style::Style *style);
+ void fillWord (Word *word, int width, int ascent, int descent,
+ bool canBeHyphenated, core::style::Style *style);
int textWidth (const char *text, int start, int len,
core::style::Style *style);
void calcTextSize (const char *text, size_t len, core::style::Style *style,
@@ -455,8 +461,8 @@ protected:
void removeChild (Widget *child);
- void addText0 (const char *text, size_t len, core::style::Style *style,
- core::Requisition *size);
+ void addText0 (const char *text, size_t len, bool canBeHyphenated,
+ core::style::Style *style, core::Requisition *size);
public:
static int CLASS_ID;
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index 5ca556c8..430f51aa 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -1,4 +1,5 @@
#include "textblock.hh"
+#include "hyphenator.hh"
#include "../lout/msg.h"
#include "../lout/misc.hh"
@@ -69,7 +70,7 @@ void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
if (totalStretchability == 0)
badnessState = TOO_LOOSE;
else {
- int ratio = 100 * (idealWidth - totalWidth) / totalStretchability;
+ ratio = 100 * (idealWidth - totalWidth) / totalStretchability;
if (ratio > 1024)
badnessState = TOO_LOOSE;
else {
@@ -81,13 +82,13 @@ void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
if (totalShrinkability == 0)
badnessState = TOO_TIGHT;
else {
- // Important: ratio is positive here.
- int ratio = 100 * (totalWidth - idealWidth) / totalShrinkability;
- if (ratio >= 100)
+ // ratio is negative here
+ ratio = 100 * (idealWidth - totalWidth) / totalShrinkability;
+ if (ratio <= - 100)
badnessState = TOO_TIGHT;
else {
badnessState = BADNESS_VALUE;
- badness = ratio * ratio * ratio;
+ badness = - ratio * ratio * ratio;
}
}
}
@@ -109,11 +110,24 @@ void Textblock::BadnessAndPenalty::setPenaltyForceBreak ()
penaltyState = FORCE_BREAK;
}
+bool Textblock::BadnessAndPenalty::lineLoose ()
+{
+ return
+ badnessState == TOO_LOOSE || (badnessState == BADNESS_VALUE && ratio > 0);
+}
+
+bool Textblock::BadnessAndPenalty::lineTight ()
+{
+ return
+ badnessState == TOO_TIGHT || (badnessState == BADNESS_VALUE && ratio < 0);
+}
+
bool Textblock::BadnessAndPenalty::lineTooTight ()
{
return badnessState == TOO_TIGHT;
}
+
bool Textblock::BadnessAndPenalty::lineMustBeBroken ()
{
return penaltyState == FORCE_BREAK;