aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--doc/dw-line-breaking.doc73
-rw-r--r--dpi/datauri.c2
-rw-r--r--dpi/downloads.cc1
-rw-r--r--dw/fltkplatform.cc4
-rw-r--r--dw/fltkplatform.hh3
-rw-r--r--dw/fltkui.cc54
-rw-r--r--dw/fltkui.hh8
-rw-r--r--dw/fltkviewbase.cc5
-rw-r--r--dw/style.hh2
-rw-r--r--dw/textblock.cc345
-rw-r--r--dw/textblock.hh95
-rw-r--r--dw/textblock_linebreaking.cc146
-rw-r--r--dw/ui.hh6
-rw-r--r--dw/widget.cc3
-rw-r--r--dw/widget.hh4
-rw-r--r--src/capi.c6
-rw-r--r--src/decode.c21
-rw-r--r--src/dialog.cc1
-rw-r--r--src/dillo.cc4
-rw-r--r--src/domain.c8
-rw-r--r--src/form.cc76
-rw-r--r--src/form.hh8
-rw-r--r--src/html.cc46
-rw-r--r--src/prefs.c6
-rw-r--r--src/prefs.h2
-rw-r--r--src/prefsparser.cc25
-rw-r--r--src/styleengine.cc8
-rw-r--r--src/table.cc6
-rw-r--r--test/dw_anchors_test.cc8
-rw-r--r--test/dw_border_test.cc6
-rw-r--r--test/dw_example.cc4
-rw-r--r--test/dw_find_test.cc6
-rw-r--r--test/dw_float_test.cc8
-rw-r--r--test/dw_images_scaled.cc4
-rw-r--r--test/dw_images_scaled2.cc8
-rw-r--r--test/dw_images_simple.cc4
-rw-r--r--test/dw_links.cc6
-rw-r--r--test/dw_links2.cc6
-rw-r--r--test/dw_lists.cc6
-rw-r--r--test/dw_resource_test.cc4
-rw-r--r--test/dw_table.cc6
-rw-r--r--test/dw_table_aligned.cc6
-rw-r--r--test/dw_ui_test.cc4
-rw-r--r--test/hyphens-etc.html6
45 files changed, 701 insertions, 361 deletions
diff --git a/ChangeLog b/ChangeLog
index 599fb3ff..805b6bec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,7 @@ dillo-3.0.3 [not released yet]
+- Support for CSS display property
- Replace polling in DNS with a pipe.
- Packed trie to optimize hyphenator memory consumption.
+ - Fix crash in datauri dpi.
Patches: Johannes Hofmann
+- Fix image input coordinates (BUG#1070)
- When location bar is given focus, temporarily show panels if hidden
@@ -21,6 +22,7 @@ dillo-3.0.3 [not released yet]
- Add some more info to various bug meter messages.
- For text selection, fix releasing mouse button outside of boundary.
- While selecting text, moving cursor outside viewport will scroll it.
+ - Make form resetting work for <select>.
Patches: corvid
+- Automatic hyphenation.
Patch: Sebastian Geerken
diff --git a/doc/dw-line-breaking.doc b/doc/dw-line-breaking.doc
index 2967e98f..8d9a1df1 100644
--- a/doc/dw-line-breaking.doc
+++ b/doc/dw-line-breaking.doc
@@ -322,35 +322,11 @@ Bugs and Things Needing Improvement
High Priority
-------------
-**Bugs in hyphenation:** There seem to be problems when breaking
-words containing hyphens already. Example: "Abtei-Stadt", which is
-divided into "Abtei-" and "Stadt", resulting possibly in
-&quot;Abtei-<span></span>-[new line]Stadt&quot;. See also below under
-"Medium Priority", on how to deal with hyphens and dashes.
+None.
Medium Priority
---------------
-**Break hyphens and dashes:** The following rules seem to be relevant:
-
-- In English, an em-dash is used with no spaces around. Breaking
- before and after the dash should be possible, perhaps with a
- penalty > 0. (In German, an en-dash (Halbgeviert) with spaces around
- is used instead.)
-- After a hyphen, which is part of a compound word, a break should be
- possible. As described above ("Abtei-Stadt"), this collides with
- hyphenation.
-
-Where to implement? In the same dynamic, lazy way like hyphenation? As
-part of hyphenation?
-
-Notice that Liang's algorithm may behave different regarding hyphens:
-"Abtei-Stadt" is (using the patterns from CTAN) divided into "Abtei-"
-and "Stadt", but "Nordrhein-Westfalen" is divided into "Nord",
-"rhein-West", "fa", "len": the part containing the hyphen
-("rhein-West") is untouched. (Sorry for the German words; if you have
-got English examples, send them me.)
-
**Incorrect calculation of extremes:** The minimal width of a text
block (as part of the width extremes, which are mainly used for
tables) is defined by everything between two possible breaks. A
@@ -410,8 +386,53 @@ lines will, when spaces are shrunken, get too long!)
Analogous considerations must be made for right-aligned and centered
text. (For centered texts, there are two adjustable spaces.)
-**Hyphens in adjacent lines:** It should be simple to assign a larger
+Solved (Must Be Documented)
+---------------------------
+
+These have been solved recently and should be documented above.
+
+*Bugs in hyphenation:* There seem to be problems when breaking words
+containing hyphens already. Example: "Abtei-Stadt", which is divided
+into "Abtei-" and "Stadt", resulting possibly in
+&quot;Abtei-<span></span>-[new line]Stadt&quot;. See also below under
+"Medium Priority", on how to deal with hyphens and dashes.
+
+**Solution:** See next.
+
+*Break hyphens and dashes:* The following rules seem to be relevant:
+
+- In English, an em-dash is used with no spaces around. Breaking
+ before and after the dash should be possible, perhaps with a
+ penalty > 0. (In German, an en-dash (Halbgeviert) with spaces around
+ is used instead.)
+- After a hyphen, which is part of a compound word, a break should be
+ possible. As described above ("Abtei-Stadt"), this collides with
+ hyphenation.
+
+Where to implement? In the same dynamic, lazy way like hyphenation? As
+part of hyphenation?
+
+Notice that Liang's algorithm may behave different regarding hyphens:
+"Abtei-Stadt" is (using the patterns from CTAN) divided into "Abtei-"
+and "Stadt", but "Nordrhein-Westfalen" is divided into "Nord",
+"rhein-West", "fa", "len": the part containing the hyphen
+("rhein-West") is untouched. (Sorry for the German words; if you have
+got English examples, send them me.)</div>
+
+**Solution for both:** This has been implemented in
+dw::Textblock::addText, in a similar way to soft hyphens. Liang's
+algorithm now only operates on the parts: "Abtei" and "Stadt";
+"Nordrhein" and "Westfalen".
+
+*Hyphens in adjacent lines:* It should be simple to assign a larger
penalty for hyphens, when the line before is already hyphenated. This
way, hyphens in adjacent lines are penalized further.
+**Solved:** There are always two penalties. Must be documented in
+detail.
+
+**Also:**
+
+- Configuration of penalties.
+
*/
diff --git a/dpi/datauri.c b/dpi/datauri.c
index 055ecd9f..0e3560ec 100644
--- a/dpi/datauri.c
+++ b/dpi/datauri.c
@@ -150,8 +150,8 @@ char *a_Url_decode_hex_str(const char *str, size_t *p_sz)
}
*dest = 0;
- new_str = dRealloc(new_str, sizeof(char) * (dest - new_str + 1));
*p_sz = (size_t)(dest - new_str);
+ new_str = dRealloc(new_str, sizeof(char) * (dest - new_str + 1));
return new_str;
}
diff --git a/dpi/downloads.cc b/dpi/downloads.cc
index 418dbd1b..a25b511e 100644
--- a/dpi/downloads.cc
+++ b/dpi/downloads.cc
@@ -30,6 +30,7 @@
#include <sys/wait.h>
#include <FL/Fl.H>
+#include <FL/fl_ask.H>
#include <FL/fl_draw.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Window.H>
diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc
index d8e95a6e..7dd87a18 100644
--- a/dw/fltkplatform.cc
+++ b/dw/fltkplatform.cc
@@ -419,11 +419,11 @@ FltkPlatform::FltkResourceFactory::createOptionMenuResource ()
}
core::ui::EntryResource *
-FltkPlatform::FltkResourceFactory::createEntryResource (int maxLength,
+FltkPlatform::FltkResourceFactory::createEntryResource (int size,
bool password,
const char *label)
{
- return new ui::FltkEntryResource (platform, maxLength, password, label);
+ return new ui::FltkEntryResource (platform, size, password, label);
}
core::ui::MultiLineTextResource *
diff --git a/dw/fltkplatform.hh b/dw/fltkplatform.hh
index 7b4272eb..64605b68 100644
--- a/dw/fltkplatform.hh
+++ b/dw/fltkplatform.hh
@@ -109,8 +109,7 @@ private:
createListResource (core::ui::ListResource::SelectionMode selectionMode,
int rows);
core::ui::OptionMenuResource *createOptionMenuResource ();
- core::ui::EntryResource *createEntryResource (int maxLength,
- bool password,
+ core::ui::EntryResource *createEntryResource (int size, bool password,
const char *label);
core::ui::MultiLineTextResource *createMultiLineTextResource (int cols,
int rows);
diff --git a/dw/fltkui.cc b/dw/fltkui.cc
index 5e4f3c56..f12306fa 100644
--- a/dw/fltkui.cc
+++ b/dw/fltkui.cc
@@ -536,11 +536,11 @@ Fl_Widget *FltkComplexButtonResource::createNewWidget (core::Allocation
// ----------------------------------------------------------------------
-FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int maxLength,
+FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int size,
bool password, const char *label):
FltkSpecificResource <dw::core::ui::EntryResource> (platform)
{
- this->maxLength = maxLength;
+ this->size = size;
this->password = password;
this->label = label ? strdup(label) : NULL;
this->label_w = 0;
@@ -615,7 +615,7 @@ void FltkEntryResource::sizeRequest (core::Requisition *requisition)
// 1.3.0 (STR #2688).
requisition->width =
(int)fl_width ("n")
- * (maxLength == UNLIMITED_MAX_LENGTH ? 10 : maxLength)
+ * (size == UNLIMITED_SIZE ? 10 : size)
+ label_w + (2 * RELIEF_X_THICKNESS);
requisition->ascent = font->ascent + RELIEF_Y_THICKNESS;
requisition->descent = font->descent + RELIEF_Y_THICKNESS;
@@ -670,6 +670,11 @@ void FltkEntryResource::setEditable (bool editable)
this->editable = editable;
}
+void FltkEntryResource::setMaxLength (int maxlen)
+{
+ ((Fl_Input *)widget)->maximum_size(maxlen);
+}
+
// ----------------------------------------------------------------------
FltkMultiLineTextResource::FltkMultiLineTextResource (FltkPlatform *platform,
@@ -1131,6 +1136,12 @@ void FltkOptionMenuResource::addItem (const char *str,
queueResize (true);
}
+void FltkOptionMenuResource::setItem (int index, bool selected)
+{
+ if (selected)
+ ((Fl_Choice *)widget)->value(menu+index);
+}
+
void FltkOptionMenuResource::pushGroup (const char *name, bool enabled)
{
Fl_Menu_Item *item = newItem();
@@ -1216,12 +1227,19 @@ void FltkListResource::widgetCallback (Fl_Widget *widget, void *data)
{
Fl_Tree_Item *fltkItem = ((Fl_Tree *) widget)->callback_item ();
int index = -1;
+
if (fltkItem)
index = (long) (fltkItem->user_data ());
if (index > -1) {
- FltkListResource *res = (FltkListResource *) data;
bool selected = fltkItem->is_selected ();
- res->itemsSelected.set (index, selected);
+
+ if (selected && fltkItem->has_children()) {
+ /* Don't permit a group to be selected. */
+ fltkItem->deselect();
+ } else {
+ FltkListResource *res = (FltkListResource *) data;
+ res->itemsSelected.set (index, selected);
+ }
}
}
@@ -1257,11 +1275,35 @@ void FltkListResource::addItem (const char *str, bool enabled, bool selected)
queueResize (true);
}
+void FltkListResource::setItem (int index, bool selected)
+{
+ Fl_Tree *tree = (Fl_Tree *) widget;
+ Fl_Tree_Item *item = tree->root()->next();
+
+ for (int i = 0; item && i < index; i++)
+ item = item->next();
+
+ if (item) {
+ bool do_callback = false;
+ itemsSelected.set (index, selected);
+ if (selected) {
+ if (mode == SELECTION_MULTIPLE) {
+ tree->select(item, do_callback);
+ } else {
+ /* callback to deselect other selected item */
+ do_callback = true;
+ tree->select_only(item, do_callback);
+ }
+ } else {
+ tree->deselect(item, do_callback);
+ }
+ }
+}
+
void FltkListResource::pushGroup (const char *name, bool enabled)
{
bool selected = false;
- /* TODO: make it impossible to select a group */
currParent = (Fl_Tree_Item *) newItem(name, enabled, selected);
queueResize (true);
}
diff --git a/dw/fltkui.hh b/dw/fltkui.hh
index ff927c80..e1845abd 100644
--- a/dw/fltkui.hh
+++ b/dw/fltkui.hh
@@ -282,7 +282,7 @@ class FltkEntryResource:
public FltkSpecificResource <dw::core::ui::EntryResource>
{
private:
- int maxLength;
+ int size;
bool password;
const char *initText;
char *label;
@@ -297,7 +297,7 @@ protected:
void setWidgetStyle (Fl_Widget *widget, core::style::Style *style);
public:
- FltkEntryResource (FltkPlatform *platform, int maxLength, bool password,
+ FltkEntryResource (FltkPlatform *platform, int size, bool password,
const char *label);
~FltkEntryResource ();
@@ -308,6 +308,7 @@ public:
void setText (const char *text);
bool isEditable ();
void setEditable (bool editable);
+ void setMaxLength (int maxlen);
};
@@ -445,6 +446,7 @@ template <class I> class FltkSelectionResource:
protected:
virtual bool setSelectedItems() { return false; }
virtual void addItem (const char *str, bool enabled, bool selected) = 0;
+ virtual void setItem (int index, bool selected) = 0;
virtual void pushGroup (const char *name, bool enabled) = 0;
virtual void popGroup () = 0;
public:
@@ -475,6 +477,7 @@ public:
~FltkOptionMenuResource ();
void addItem (const char *str, bool enabled, bool selected);
+ void setItem (int index, bool selected);
void pushGroup (const char *name, bool enabled);
void popGroup ();
@@ -506,6 +509,7 @@ public:
~FltkListResource ();
void addItem (const char *str, bool enabled, bool selected);
+ void setItem (int index, bool selected);
void pushGroup (const char *name, bool enabled);
void popGroup ();
diff --git a/dw/fltkviewbase.cc b/dw/fltkviewbase.cc
index d9782a4e..0977aac5 100644
--- a/dw/fltkviewbase.cc
+++ b/dw/fltkviewbase.cc
@@ -538,6 +538,11 @@ void FltkWidgetView::drawText (core::style::Font *font,
core::style::Color::Shading shading,
int X, int Y, const char *text, int len)
{
+ //printf ("drawText (..., %d, %d, '", X, Y);
+ //for (int i = 0; i < len; i++)
+ // putchar (text[i]);
+ //printf ("'\n");
+
FltkFont *ff = (FltkFont*)font;
fl_font(ff->font, ff->size);
fl_color(((FltkColor*)color)->colors[shading]);
diff --git a/dw/style.hh b/dw/style.hh
index 6b492793..0df5c5e0 100644
--- a/dw/style.hh
+++ b/dw/style.hh
@@ -544,7 +544,7 @@ protected:
void copyAttrs (StyleAttrs *attrs);
public:
- inline static Style *create (Layout *layout, StyleAttrs *attrs)
+ inline static Style *create (StyleAttrs *attrs)
{
Style *style = styleTable->get (attrs);
if (style) {
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 1fbf0032..5d43f653 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -34,13 +34,86 @@
static dw::core::style::Tooltip *hoverTooltip = NULL;
-
using namespace lout;
namespace dw {
int Textblock::CLASS_ID = -1;
+Textblock::DivChar Textblock::divChars[NUM_DIV_CHARS] = {
+ // soft hyphen (U+00AD)
+ { "\xc2\xad", true, false, true, PENALTY_HYPHEN, -1 },
+ // simple hyphen-minus: same penalties like automatic or soft hyphens
+ { "-", false, true, true, -1, PENALTY_HYPHEN },
+ // (unconditional) hyphen (U+2010): handled exactly like minus-hyphen.
+ { "\xe2\x80\x90", false, true, true, -1, PENALTY_HYPHEN },
+ // em dash (U+2014): breaks on both sides are allowed (but see below).
+ { "\xe2\x80\x94", false, true, false,
+ PENALTY_EM_DASH_LEFT, PENALTY_EM_DASH_RIGHT }
+};
+
+// Standard values are defined here. The values are already multiplied
+// with 100.
+//
+// Some examples (details are described in doc/dw-line-breaking.doc):
+//
+// 0 = Perfect line; as penalty used for normal spaces.
+
+// 1 (100 here) = A justified line with spaces having 150% or 67% of
+// the ideal space width has this as badness.
+//
+// 8 (800 here) = A justified line with spaces twice as wide as
+// ideally has this as badness.
+//
+// The second value is used when the line before ends with a hyphen,
+// dash etc.
+
+int Textblock::penalties[PENALTY_NUM][2] = {
+ // Penalties for all hyphens.
+ { 100, 800 },
+ // Penalties for a break point *left* of an em-dash: rather large,
+ // so that a break on the *right* side is preferred.
+ { 800, 800 },
+ // Penalties for a break point *right* of an em-dash: like hyphens.
+ { 100, 800 }
+};
+
+/**
+ * The character which is used to draw a hyphen at the end of a line,
+ * either caused by automatic hyphenation, or by soft hyphens.
+ *
+ * Initially, soft hyphens were used, but they are not drawn on some
+ * platforms. Also, unconditional hyphens (U+2010) are not available
+ * in many fonts; so, a simple hyphen-minus is used.
+ */
+const char *Textblock::hyphenDrawChar = "-";
+
+void Textblock::setPenaltyHyphen (int penaltyHyphen)
+{
+ penalties[PENALTY_HYPHEN][0] = penaltyHyphen;
+}
+
+void Textblock::setPenaltyHyphen2 (int penaltyHyphen2)
+{
+ penalties[PENALTY_HYPHEN][1] = penaltyHyphen2;
+}
+
+void Textblock::setPenaltyEmDashLeft (int penaltyLeftEmDash)
+{
+ penalties[PENALTY_EM_DASH_LEFT][0] = penaltyLeftEmDash;
+ penalties[PENALTY_EM_DASH_LEFT][1] = penaltyLeftEmDash;
+}
+
+void Textblock::setPenaltyEmDashRight (int penaltyRightEmDash)
+{
+ penalties[PENALTY_EM_DASH_RIGHT][0] = penaltyRightEmDash;
+}
+
+void Textblock::setPenaltyEmDashRight2 (int penaltyRightEmDash2)
+{
+ penalties[PENALTY_EM_DASH_RIGHT][1] = penaltyRightEmDash2;
+}
+
Textblock::Textblock (bool limitTextWidth)
{
registerName ("dw::Textblock", &CLASS_ID);
@@ -313,7 +386,8 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
}
// Minimum: between two *possible* breaks (or at the end).
- if (word->badnessAndPenalty.lineCanBeBroken () || atLastWord) {
+ // TODO: Explain why index 1 is used in lineCanBeBroken().
+ if (word->badnessAndPenalty.lineCanBeBroken (1) || atLastWord) {
parMin += wordExtremes.minWidth + word->hyphenWidth;
extremes->minWidth = misc::max (extremes->minWidth, parMin);
parMin = 0;
@@ -323,7 +397,9 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
parMin += wordExtremes.minWidth + word->origSpace;
// Maximum: between two *necessary* breaks (or at the end).
- if (word->badnessAndPenalty.lineMustBeBroken () || atLastWord) {
+ // TODO: lineMustBeBroken should be independent of the
+ // penalty index?
+ if (word->badnessAndPenalty.lineMustBeBroken (1) || atLastWord) {
parMax += wordExtremes.maxWidth + word->hyphenWidth;
extremes->maxWidth = misc::max (extremes->maxWidth, parMax);
parMax = 0;
@@ -1010,6 +1086,7 @@ void Textblock::drawText(core::View *view, core::style::Style *style,
break;
}
}
+
view->drawText(style->font, style->color, shading, x, y,
str ? str : text + start, str ? strlen(str) : len);
if (str)
@@ -1031,7 +1108,7 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2,
{
core::style::Style *style = words->getRef(wordIndex1)->style;
bool drawHyphen = wordIndex2 == line->lastWord
- && words->getRef(wordIndex2)->hyphenWidth > 0;
+ && (words->getRef(wordIndex2)->flags & Word::DIV_CHAR_AT_EOL);
if (style->hasBackground ()) {
int w = 0;
@@ -1055,8 +1132,8 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2,
l += strlen (w->content.text);
totalWidth += w->size.width;
}
-
- char text[l + (drawHyphen ? 2 : 0) + 1];
+
+ char text[l + (drawHyphen ? strlen (hyphenDrawChar) : 0) + 1];
int p = 0;
for (int i = wordIndex1; i <= wordIndex2; i++) {
const char * t = words->getRef(i)->content.text;
@@ -1065,8 +1142,8 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2,
}
if(drawHyphen) {
- text[p++] = 0xc2;
- text[p++] = 0xad;
+ for (int i = 0; hyphenDrawChar[i]; i++)
+ text[p++] = hyphenDrawChar[i];
text[p++] = 0;
}
@@ -1249,7 +1326,8 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
} else {
int wordIndex2 = wordIndex;
while (wordIndex2 < line->lastWord &&
- words->getRef(wordIndex2)->hyphenWidth > 0 &&
+ (words->getRef(wordIndex2)->flags
+ & Word::DRAW_AS_ONE_TEXT) &&
word->style == words->getRef(wordIndex2 + 1)->style)
wordIndex2++;
@@ -1263,6 +1341,7 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
word = words->getRef(wordIndex);
}
}
+
if (word->effSpace > 0 && wordIndex < line->lastWord &&
words->getRef(wordIndex + 1)->content.type !=
core::Content::BREAK) {
@@ -1429,9 +1508,9 @@ void Textblock::fillWord (Word *word, int width, int ascent, int descent,
word->origSpace = word->effSpace = word->stretchability =
word->shrinkability = 0;
word->hyphenWidth = 0;
- word->badnessAndPenalty.setPenaltyProhibitBreak ();
+ word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK);
word->content.space = false;
- word->canBeHyphenated = canBeHyphenated;
+ word->flags = canBeHyphenated ? Word::CAN_BE_HYPHENATED : 0;
word->style = style;
word->spaceStyle = style;
@@ -1548,79 +1627,195 @@ void Textblock::calcTextSize (const char *text, size_t len,
}
/**
- * Add a word to the page structure. If it contains soft hyphens, it is
- * divided.
+ * Add a word to the page structure. If it contains dividing
+ * characters (hard or soft hyphens, em-dashes, etc.), it is divided.
*/
void Textblock::addText (const char *text, size_t len,
core::style::Style *style)
{
PRINTF ("[%p] ADD_TEXT (%d characters)\n", this, (int)len);
- // Count hyphens.
- int numHyphens = 0;
- for (int i = 0; i < (int)len - 1; i++)
- // (0xc2, 0xad) is the UTF-8 representation of a soft hyphen (Unicode
- // 0xc2).
- if((unsigned char)text[i] == 0xc2 && (unsigned char)text[i + 1] == 0xad)
- numHyphens++;
-
- if (numHyphens == 0) {
- // Simple (and common) case: no soft hyphens. May still be hyphenated
- // automatically.
+ // Count dividing characters.
+ int numParts = 1;
+
+ for (int i = 0; i < (int)len;
+ i < (int)len && (i = layout->nextGlyph (text, i))) {
+ int foundDiv = -1;
+ for (int j = 0; foundDiv == -1 && j < NUM_DIV_CHARS; j++) {
+ int lDiv = strlen (divChars[j].s);
+ if (i <= (int)len - lDiv) {
+ if (memcmp (text + i, divChars[j].s, lDiv * sizeof (char)) == 0)
+ foundDiv = j;
+ }
+ }
+
+ if (foundDiv != -1) {
+ if (divChars[foundDiv].penaltyIndexLeft != -1)
+ numParts ++;
+ if (divChars[foundDiv].penaltyIndexRight != -1)
+ numParts ++;
+ }
+ }
+
+ if (numParts == 1) {
+ // Simple (and common) case: no dividing characters. May still
+ // be hyphenated automatically.
core::Requisition size;
calcTextSize (text, len, style, &size);
addText0 (text, len, true, style, &size);
} else {
- PRINTF("HYPHENATION: '");
+ PRINTF ("HYPHENATION: '");
for (size_t i = 0; i < len; i++)
PUTCHAR(text[i]);
- PRINTF("', with %d hyphen(s)\n", numHyphens);
+ PRINTF ("', with %d parts\n", numParts);
// Store hyphen positions.
- int n = 0, hyphenPos[numHyphens], breakPos[numHyphens];
- for (size_t i = 0; i < len - 1; i++)
- if((unsigned char)text[i] == 0xc2 &&
- (unsigned char)text[i + 1] == 0xad) {
- hyphenPos[n] = i;
- breakPos[n] = i - 2 * n;
- n++;
+ int n = 0, totalLenCharRemoved = 0;
+ int partPenaltyIndex[numParts - 1];
+ int partStart[numParts], partEnd[numParts];
+ bool charRemoved[numParts - 1], canBeHyphenated[numParts + 1];
+ bool permDivChar[numParts - 1], unbreakableForMinWidth[numParts - 1];
+ canBeHyphenated[0] = canBeHyphenated[numParts] = true;
+ partStart[0] = 0;
+ partEnd[numParts - 1] = len;
+
+ for (int i = 0; i < (int)len;
+ i < (int)len && (i = layout->nextGlyph (text, i))) {
+ int foundDiv = -1;
+ for (int j = 0; foundDiv == -1 && j < NUM_DIV_CHARS; j++) {
+ int lDiv = strlen (divChars[j].s);
+ if (i <= (int)len - lDiv) {
+ if (memcmp (text + i, divChars[j].s, lDiv * sizeof (char)) == 0)
+ foundDiv = j;
+ }
+ }
+
+ if (foundDiv != -1) {
+ int lDiv = strlen (divChars[foundDiv].s);
+
+ if (divChars[foundDiv].charRemoved) {
+ assert (divChars[foundDiv].penaltyIndexLeft != -1);
+ assert (divChars[foundDiv].penaltyIndexRight == -1);
+
+ partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexLeft;
+ charRemoved[n] = true;
+ permDivChar[n] = false;
+ unbreakableForMinWidth[n] =
+ divChars[foundDiv].unbreakableForMinWidth;
+ canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated;
+ partEnd[n] = i;
+ partStart[n + 1] = i + lDiv;
+ n++;
+ totalLenCharRemoved += lDiv;
+ } else {
+ assert (divChars[foundDiv].penaltyIndexLeft != -1 ||
+ divChars[foundDiv].penaltyIndexRight != -1);
+
+ if (divChars[foundDiv].penaltyIndexLeft != -1) {
+ partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexLeft;
+ charRemoved[n] = false;
+ permDivChar[n] = false;
+ unbreakableForMinWidth[n] =
+ divChars[foundDiv].unbreakableForMinWidth;
+ canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated;
+ partEnd[n] = i;
+ partStart[n + 1] = i;
+ n++;
+ }
+
+ if (divChars[foundDiv].penaltyIndexRight != -1) {
+ partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexRight;
+ charRemoved[n] = false;
+ permDivChar[n] = true;
+ unbreakableForMinWidth[n] =
+ divChars[foundDiv].unbreakableForMinWidth;
+ canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated;
+ partEnd[n] = i + lDiv;
+ partStart[n + 1] = i + lDiv;
+ n++;
+ }
+ }
}
+ }
- // Get text without hyphens. (There are numHyphens + 1 parts in the word,
- // and 2 * numHyphens bytes less, 2 for each hyphen, are needed.)
- char textWithoutHyphens[len - 2 * numHyphens];
- int start = 0; // related to "text"
- for (int i = 0; i < numHyphens + 1; i++) {
- int end = (i == numHyphens) ? len : hyphenPos[i];
- memmove (textWithoutHyphens + start - 2 * i, text + start,
- end - start);
- start = end + 2;
+ // Get text without removed characters, e. g. hyphens.
+ const char *textWithoutHyphens;
+ char textWithoutHyphensBuf[len - totalLenCharRemoved];
+ int *breakPosWithoutHyphens, breakPosWithoutHyphensBuf[numParts - 1];
+
+ if (totalLenCharRemoved == 0) {
+ // No removed characters: take original arrays.
+ textWithoutHyphens = text;
+ // Ends are also break positions, except the last end, which
+ // is superfluous, but does not harm (since arrays in C/C++
+ // does not have an implicit length).
+ breakPosWithoutHyphens = partEnd;
+ } else {
+ // Copy into special buffers.
+ textWithoutHyphens = textWithoutHyphensBuf;
+ breakPosWithoutHyphens = breakPosWithoutHyphensBuf;
+
+ int n = 0;
+ for (int i = 0; i < numParts; i++) {
+ memmove (textWithoutHyphensBuf + n, text + partStart[i],
+ partEnd[i] - partStart[i]);
+ n += partEnd[i] - partStart[i];
+ if (i < numParts - 1)
+ breakPosWithoutHyphensBuf[i] = n;
+ }
}
PRINTF("H... without hyphens: '");
- for (size_t i = 0; i < len - 2 * numHyphens; i++)
+ for (size_t i = 0; i < len - totalLenCharRemoved; i++)
PUTCHAR(textWithoutHyphens[i]);
PRINTF("'\n");
- core::Requisition wordSize[numHyphens + 1];
- calcTextSizes (textWithoutHyphens, len - 2 * numHyphens, style,
- numHyphens, breakPos, wordSize);
+ core::Requisition wordSize[numParts];
+ calcTextSizes (textWithoutHyphens, len - totalLenCharRemoved, style,
+ numParts - 1, breakPosWithoutHyphens, wordSize);
// Finished!
- for (int i = 0; i < numHyphens + 1; i++) {
- int start = (i == 0) ? 0 : hyphenPos[i - 1] + 2;
- int end = (i == numHyphens) ? len : hyphenPos[i];
- // Do not anymore hyphen automatically.
- addText0 (text + start, end - start, false, style, &wordSize[i]);
+ for (int i = 0; i < numParts; i++) {
+ addText0 (text + partStart[i], partEnd[i] - partStart[i],
+ // If this parts adjoins at least one division
+ // characters, for which canBeHyphenated is set to
+ // false (this is the case for soft hyphens), do
+ // not hyphenate.
+ canBeHyphenated[i] && canBeHyphenated[i + 1],
+ style, &wordSize[i]);
PRINTF("H... [%d] '", i);
- for (int j = start; j < end; j++)
+ for (int j = partStart[i]; j < partEnd[i]; j++)
PUTCHAR(text[j]);
PRINTF("' added\n");
- if(i < numHyphens) {
- addHyphen ();
- PRINTF("H... yphen added\n");
+ if(i < numParts - 1) {
+ Word *word = words->getLastRef();
+
+ word->badnessAndPenalty
+ .setPenalties (penalties[partPenaltyIndex[i]][0],
+ penalties[partPenaltyIndex[i]][1]);
+
+ if (charRemoved[i]) {
+ // Currently, only unconditional hyphens (UTF-8:
+ // "\xe2\x80\x90") can be used. See also drawWord, last
+ // section "if (drawHyphen)".
+ // Could be extended by adding respective members to
+ // DivChar and Word.
+ word->hyphenWidth =
+ layout->textWidth (word->style->font, hyphenDrawChar,
+ strlen (hyphenDrawChar));
+ word->flags |= Word::DIV_CHAR_AT_EOL;
+ }
+
+ if (permDivChar[i])
+ word->flags |= Word::PERM_DIV_CHAR;
+ if (unbreakableForMinWidth[i])
+ word->flags |= Word::UNBREAKABLE_FOR_MIN_WIDTH;
+
+ word->flags |= Word::DRAW_AS_ONE_TEXT;
+
+ accumulateWordData (words->size() - 1);
}
}
}
@@ -1641,7 +1836,8 @@ void Textblock::calcTextSizes (const char *text, size_t textLen,
PUTCHAR(text[i + lastStart]);
PRINTF("' -> %d\n", wordSize[numBreaks].width);
- // The rest is more complicated. TODO Documentation.
+ // The rest is more complicated. See dw-line-breaking, section
+ // "Hyphens".
for (int i = numBreaks - 1; i >= 0; i--) {
int start = (i == 0) ? 0 : breakPos[i - 1];
calcTextSize (text + start, textLen - start, style, &wordSize[i]);
@@ -1664,6 +1860,11 @@ void Textblock::calcTextSizes (const char *text, size_t textLen,
void Textblock::addText0 (const char *text, size_t len, bool canBeHyphenated,
core::style::Style *style, core::Requisition *size)
{
+ //printf("[%p] addText0 ('", this);
+ //for (size_t i = 0; i < len; i++)
+ // putchar(text[i]);
+ //printf("', %s, ...)\n", canBeHyphenated ? "true" : "false");
+
Word *word = addWord (size->width, size->ascent, size->descent,
canBeHyphenated, style);
word->content.type = core::Content::TEXT;
@@ -1826,7 +2027,9 @@ void Textblock::fillSpace (Word *word, core::style::Style *style)
*/
void Textblock::setBreakOption (Word *word, core::style::Style *style)
{
- if (!word->badnessAndPenalty.lineMustBeBroken()) {
+ // TODO: lineMustBeBroken should be independent of the penalty
+ // index? Otherwise, examine the last line.
+ if (!word->badnessAndPenalty.lineMustBeBroken(0)) {
switch (style->whiteSpace) {
case core::style::WHITE_SPACE_NORMAL:
case core::style::WHITE_SPACE_PRE_LINE:
@@ -1836,26 +2039,12 @@ void Textblock::setBreakOption (Word *word, core::style::Style *style)
case core::style::WHITE_SPACE_PRE:
case core::style::WHITE_SPACE_NOWRAP:
- word->badnessAndPenalty.setPenaltyProhibitBreak ();
+ word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK);
break;
}
}
}
-void Textblock::addHyphen ()
-{
- int wordIndex = words->size () - 1;
-
- if (wordIndex >= 0) {
- Word *word = words->getRef(wordIndex);
-
- word->badnessAndPenalty.setPenalty (HYPHEN_BREAK);
- // TODO Optimize? Like spaces?
- word->hyphenWidth = layout->textWidth (word->style->font, "\xc2\xad", 2);
-
- accumulateWordData (wordIndex);
- }
-}
/**
* Cause a paragraph break
@@ -1930,7 +2119,7 @@ void Textblock::addParbreak (int space, core::style::Style *style)
word = addWord (0, 0, 0, false, style);
word->content.type = core::Content::BREAK;
- word->badnessAndPenalty.setPenaltyForceBreak ();
+ word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK);
word->content.breakSpace = space;
wordWrap (words->size () - 1, false);
}
@@ -1953,7 +2142,7 @@ void Textblock::addLinebreak (core::style::Style *style)
word = addWord (0, 0, 0, false, style);
word->content.type = core::Content::BREAK;
- word->badnessAndPenalty.setPenaltyForceBreak ();
+ word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK);
word->content.breakSpace = 0;
wordWrap (words->size () - 1, false);
}
@@ -2058,14 +2247,13 @@ void Textblock::changeLinkColor (int link, int newColor)
styleAttrs = *old_style;
styleAttrs.color = core::style::Color::create (layout,
newColor);
- word->style = core::style::Style::create (layout, &styleAttrs);
+ word->style = core::style::Style::create (&styleAttrs);
old_style->unref();
old_style = word->spaceStyle;
styleAttrs = *old_style;
styleAttrs.color = core::style::Color::create (layout,
newColor);
- word->spaceStyle =
- core::style::Style::create(layout, &styleAttrs);
+ word->spaceStyle = core::style::Style::create(&styleAttrs);
old_style->unref();
break;
}
@@ -2076,8 +2264,7 @@ void Textblock::changeLinkColor (int link, int newColor)
newColor);
styleAttrs.setBorderColor(
core::style::Color::create (layout, newColor));
- widget->setStyle(
- core::style::Style::create (layout, &styleAttrs));
+ widget->setStyle(core::style::Style::create (&styleAttrs));
break;
}
default:
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 3d1f676c..c7d53eeb 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -154,14 +154,19 @@ private:
* badness is not well defined, so fiddling with the penalties is a
* bit difficult.
*/
+
+ enum {
+ PENALTY_FORCE_BREAK = INT_MIN,
+ PENALTY_PROHIBIT_BREAK = INT_MAX
+ };
+
class BadnessAndPenalty
{
private:
enum { NOT_STRETCHABLE, QUITE_LOOSE, BADNESS_VALUE, TOO_TIGHT }
badnessState;
- enum { FORCE_BREAK, PROHIBIT_BREAK, PENALTY_VALUE } penaltyState;
int ratio; // ratio is only defined when badness is defined
- int badness, penalty;
+ int badness, penalty[2];
// For debugging: define DEBUG for more informations in print().
#ifdef DEBUG
@@ -193,39 +198,45 @@ private:
// etc. works.
};
+ void setSinglePenalty (int index, int penalty);
int badnessValue (int infLevel);
- int penaltyValue (int infLevel);
+ int penaltyValue (int index, int infLevel);
public:
void calcBadness (int totalWidth, int idealWidth,
int totalStretchability, int totalShrinkability);
- void setPenalty (int penalty);
- void setPenaltyProhibitBreak ();
- void setPenaltyForceBreak ();
+ inline void setPenalty (int penalty) { setPenalties (penalty, penalty); }
+ void setPenalties (int penalty1, int penalty2);
bool lineLoose ();
bool lineTight ();
bool lineTooTight ();
- bool lineMustBeBroken ();
- bool lineCanBeBroken ();
- int compareTo (BadnessAndPenalty *other);
+ bool lineMustBeBroken (int penaltyIndex);
+ bool lineCanBeBroken (int penaltyIndex);
+ int compareTo (int penaltyIndex, BadnessAndPenalty *other);
void print ();
};
+ enum { PENALTY_HYPHEN, PENALTY_EM_DASH_LEFT, PENALTY_EM_DASH_RIGHT,
+ PENALTY_NUM };
+ enum { NUM_DIV_CHARS = 4 };
+
+ typedef struct
+ {
+ const char *s;
+ bool charRemoved, canBeHyphenated, unbreakableForMinWidth;
+ int penaltyIndexLeft, penaltyIndexRight;
+ } DivChar;
+
+ static DivChar divChars[NUM_DIV_CHARS];
+
+ static const char *hyphenDrawChar;
+
Textblock *containingBlock;
OutOfFlowMgr *outOfFlowMgr;
protected:
- enum {
- /**
- * The penalty for hyphens, multiplied by 100. So, 100 means
- * 1.0. See dw::Textblock::BadnessAndPenalty::setPenalty for
- * more details.
- */
- HYPHEN_BREAK = 100
- };
-
struct Line
{
int firstWord; /* first word's index in word vector */
@@ -273,6 +284,26 @@ protected:
struct Word
{
+ enum {
+ /** Can be hyphenated automatically. (Cleared after
+ * hyphenation.) */
+ CAN_BE_HYPHENATED = 1 << 0,
+ /** Must be drawn with a hyphen, when at the end of the line. */
+ DIV_CHAR_AT_EOL = 1 << 1,
+ /** Is or ends with a "division character", which is part of
+ * the word. */
+ PERM_DIV_CHAR = 1 << 2,
+ /** This word must be drawn, together with the following
+ * word(s), by only one call of View::drawText(), to get
+ * kerning, ligatures etc. right. The last of the words drawn
+ * as one text does *not* have this flag set. */
+ DRAW_AS_ONE_TEXT = 1 << 3,
+ /* When calculating the minimal width (as part of extremes),
+ * do not consider this word as breakable. This flag is
+ * ignored when the line is actually broken. */
+ UNBREAKABLE_FOR_MIN_WIDTH = 1 << 4,
+ };
+
/* TODO: perhaps add a xLeft? */
core::Requisition size;
/* Space after the word, only if it's not a break: */
@@ -286,8 +317,9 @@ protected:
* this is the last word of the line, and
* "hyphenWidth > 0" is also used to decide
* whether to draw a hyphen. */
+ short flags;
+ short penaltyIndex;
core::Content content;
- bool canBeHyphenated;
// accumulated values, relative to the beginning of the line
int totalWidth; /* The sum of all word widths; plus all
@@ -370,6 +402,14 @@ protected:
bool mustQueueResize;
+ /**
+ * The penalties for hyphens and other, multiplied by 100. So, 100
+ * means 1.0. INT_MAX and INT_MIN are also allowed. See
+ * dw::Textblock::BadnessAndPenalty::setPenalty for more
+ * details. Set from preferences.
+ */
+ static int penalties[PENALTY_NUM][2];
+
bool limitTextWidth; /* from preferences */
int redrawY;
@@ -561,6 +601,16 @@ protected:
{
return lineYOffsetCanvas (lines->getRef (lineIndex));
}
+
+ inline int calcPenaltyIndexForNewLine ()
+ {
+ if (lines->size() == 0)
+ return 0;
+ else
+ return
+ (words->getRef(lines->getLastRef()->lastWord)->flags &
+ (Word::DIV_CHAR_AT_EOL | Word::PERM_DIV_CHAR)) ? 1 : 0;
+ }
Textblock *getTextblockForLine (Line *line);
Textblock *getTextblockForLine (int lineNo);
@@ -613,6 +663,12 @@ protected:
public:
static int CLASS_ID;
+ static void setPenaltyHyphen (int penaltyHyphen);
+ static void setPenaltyHyphen2 (int penaltyHyphen2);
+ static void setPenaltyEmDashLeft (int penaltyLeftEmDash);
+ static void setPenaltyEmDashRight (int penaltyRightEmDash);
+ static void setPenaltyEmDashRight2 (int penaltyRightEmDash2);
+
Textblock(bool limitTextWidth);
~Textblock();
@@ -640,7 +696,6 @@ public:
setBreakOption (words->getRef(wordIndex), style);
}
- void addHyphen();
void addParbreak (int space, core::style::Style *style);
void addLinebreak (core::style::Style *style);
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index f97bd9b5..67798fd6 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -31,22 +31,14 @@ int Textblock::BadnessAndPenalty::badnessValue (int infLevel)
return 0;
}
-int Textblock::BadnessAndPenalty::penaltyValue (int infLevel)
+int Textblock::BadnessAndPenalty::penaltyValue (int index, int infLevel)
{
- switch (penaltyState) {
- case FORCE_BREAK:
+ if (penalty[index] == INT_MIN)
return infLevel == INF_PENALTIES ? -1 : 0;
-
- case PROHIBIT_BREAK:
+ else if (penalty[index] == INT_MAX)
return infLevel == INF_PENALTIES ? 1 : 0;
-
- case PENALTY_VALUE:
- return infLevel == INF_VALUE ? penalty : 0;
- }
-
- // compiler happiness
- lout::misc::assertNotReached ();
- return 0;
+ else
+ return infLevel == INF_VALUE ? penalty[index] : 0;
}
void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
@@ -98,6 +90,9 @@ void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
* to deal with fractional numbers, without having to use floating
* point numbers. So, to set a penalty to 0.5, pass 50.
*
+ * INT_MAX and INT_MIN (representing inf and -inf, respectively) are
+ * also allowed.
+ *
* The definition of penalties depends on the definition of badness,
* which adheres to the description in \ref dw-line-breaking, section
* "Criteria for Line-Breaking". The exact calculation may vary, but
@@ -105,27 +100,28 @@ void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
* fitting line has a badness of 0. (ii)&nbsp;A line, where all spaces
* are extended by exactly the stretchability, as well as a line, where
* all spaces are reduced by the shrinkability, have a badness of 1.
+ *
+ * (TODO plural: penalties, not penalty. Correct above comment)
*/
-void Textblock::BadnessAndPenalty::setPenalty (int penalty)
-{
- // This factor consists of: (i) 100^3, since in calcBadness(), the
- // ratio is multiplied with 100 (again, to use integer numbers for
- // fractional numbers), and the badness (which has to be compared
- // to the penalty!) is the third power or it; (ii) the denominator
- // 100, of course, since 100 times the penalty is passed to this
- // method.
- this->penalty = penalty * (100 * 100 * 100 / 100);
- penaltyState = PENALTY_VALUE;
-}
-
-void Textblock::BadnessAndPenalty::setPenaltyProhibitBreak ()
+void Textblock::BadnessAndPenalty::setPenalties (int penalty1, int penalty2)
{
- penaltyState = PROHIBIT_BREAK;
+ // TODO Check here some cases, e.g. both or no penalty INT_MIN.
+ setSinglePenalty(0, penalty1);
+ setSinglePenalty(1, penalty2);
}
-void Textblock::BadnessAndPenalty::setPenaltyForceBreak ()
+void Textblock::BadnessAndPenalty::setSinglePenalty (int index, int penalty)
{
- penaltyState = FORCE_BREAK;
+ if (penalty == INT_MAX || penalty == INT_MIN)
+ this->penalty[index] = penalty;
+ else
+ // This factor consists of: (i) 100^3, since in calcBadness(), the
+ // ratio is multiplied with 100 (again, to use integer numbers for
+ // fractional numbers), and the badness (which has to be compared
+ // to the penalty!) is the third power or it; (ii) the denominator
+ // 100, of course, since 100 times the penalty is passed to this
+ // method.
+ this->penalty[index] = penalty * (100 * 100 * 100 / 100);
}
bool Textblock::BadnessAndPenalty::lineLoose ()
@@ -147,21 +143,23 @@ bool Textblock::BadnessAndPenalty::lineTooTight ()
}
-bool Textblock::BadnessAndPenalty::lineMustBeBroken ()
+bool Textblock::BadnessAndPenalty::lineMustBeBroken (int penaltyIndex)
{
- return penaltyState == FORCE_BREAK;
+ return penalty[penaltyIndex] == PENALTY_FORCE_BREAK;
}
-bool Textblock::BadnessAndPenalty::lineCanBeBroken ()
+bool Textblock::BadnessAndPenalty::lineCanBeBroken (int penaltyIndex)
{
- return penaltyState != PROHIBIT_BREAK;
+ return penalty[penaltyIndex] != PENALTY_PROHIBIT_BREAK;
}
-int Textblock::BadnessAndPenalty::compareTo (BadnessAndPenalty *other)
+int Textblock::BadnessAndPenalty::compareTo (int penaltyIndex,
+ BadnessAndPenalty *other)
{
for (int l = INF_MAX; l >= 0; l--) {
- int thisValue = badnessValue (l) + penaltyValue (l);
- int otherValue = other->badnessValue (l) + other->penaltyValue (l);
+ int thisValue = badnessValue (l) + penaltyValue (penaltyIndex, l);
+ int otherValue =
+ other->badnessValue (l) + other->penaltyValue (penaltyIndex, l);
if (thisValue != otherValue)
return thisValue - otherValue;
@@ -197,19 +195,19 @@ void Textblock::BadnessAndPenalty::print ()
printf (" <no debug> + ");
#endif
- switch (penaltyState) {
- case FORCE_BREAK:
- printf ("-inf");
- break;
-
- case PROHIBIT_BREAK:
- printf ("inf");
- break;
+ printf ("(");
+ for (int i = 0; i < 2; i++) {
+ if (penalty[i] == INT_MIN)
+ printf ("-inf");
+ else if (penalty[i] == INT_MAX)
+ printf ("inf");
+ else
+ printf ("%d", penalty[i]);
- case PENALTY_VALUE:
- printf ("%d", penalty);
- break;
+ if (i == 0)
+ printf (", ");
}
+ printf (")");
}
void Textblock::printWordShort (Word *word)
@@ -237,11 +235,14 @@ void Textblock::printWordShort (Word *word)
printf ("<?>");
break;
}
+
+ printf (" (flags = %d)", word->flags);
}
void Textblock::printWord (Word *word)
{
printWordShort (word);
+
printf (" [%d / %d + %d - %d => %d + %d - %d] => ",
word->size.width, word->origSpace, word->stretchability,
word->shrinkability, word->totalWidth, word->totalStretchability,
@@ -317,6 +318,11 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
Word *lastWordOfLine = words->getRef(lastWord);
// Word::totalWidth includes the hyphen (which is what we want here).
int lineWidth = lastWordOfLine->totalWidth;
+ // "lineWidth" is relative to leftOffset, so we may have to add
+ // "line1OffsetEff" (remember: this is, for list items, negative).
+ if (lines->size () == 0)
+ lineWidth += line1OffsetEff;
+
int maxOfMinWidth, sumOfMaxWidth;
accumulateWordExtremes (firstWord, lastWord, &maxOfMinWidth,
&sumOfMaxWidth);
@@ -375,7 +381,9 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
line->maxParMin = misc::max (maxOfMinWidth, prevLine->maxParMin);
Word *lastWordOfPrevLine = words->getRef (prevLine->lastWord);
- if (lastWordOfPrevLine->badnessAndPenalty.lineMustBeBroken ())
+ // TODO: lineMustBeBroken should be independent of the penalty
+ // index? Otherwise, examine the last line.
+ if (lastWordOfPrevLine->badnessAndPenalty.lineMustBeBroken (0))
// This line starts a new paragraph.
line->parMax = sumOfMaxWidth;
else
@@ -388,7 +396,9 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
// "maxParMax" is only set, when this line is the last line of the
// paragraph.
Word *lastWordOfThisLine = words->getRef (line->lastWord);
- if (lastWordOfThisLine->badnessAndPenalty.lineMustBeBroken ())
+ // TODO: lineMustBeBroken should be independent of the penalty
+ // index? Otherwise, examine the last line.
+ if (lastWordOfThisLine->badnessAndPenalty.lineMustBeBroken (0))
// Paragraph ends here.
line->maxParMax =
misc::max (lastMaxParMax,
@@ -439,7 +449,8 @@ void Textblock::accumulateWordExtremes (int firstWord, int lastWord,
// Minimum: between two *possible* breaks (or at the end).
// TODO This is redundant to getExtremesImpl().
- if (word->badnessAndPenalty.lineCanBeBroken () || atLastWord) {
+ // TODO: Again, index 1 is used for lineCanBeBroken(). See getExtremes().
+ if (word->badnessAndPenalty.lineCanBeBroken (1) || atLastWord) {
parMin += extremes.minWidth + word->hyphenWidth;
*maxOfMinWidth = misc::max (*maxOfMinWidth, parMin);
parMin = 0;
@@ -497,7 +508,6 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
// even earlier.
diffYToContainingBlock + top + getStyle()->boxOffsetY());
-
// TODO: compare old/new values of calcAvailWidth(...);
int firstIndex =
lines->size() == 0 ? 0 : lines->getLastRef()->lastWord + 1;
@@ -505,6 +515,8 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
accumulateWordData (i);
}
+ int penaltyIndex = calcPenaltyIndexForNewLine ();
+
bool newLine;
do {
bool tempNewLine = false;
@@ -518,14 +530,16 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
tempNewLine = true;
PRINTF (" NEW LINE: last word\n");
} else if (wordIndex >= firstIndex &&
- word->badnessAndPenalty.lineMustBeBroken ()) {
+ // TODO: lineMustBeBroken should be independent of
+ // the penalty index?
+ word->badnessAndPenalty.lineMustBeBroken (penaltyIndex)) {
newLine = true;
searchUntil = wordIndex;
PRINTF (" NEW LINE: forced break\n");
} else if (wordIndex > firstIndex &&
word->badnessAndPenalty.lineTooTight () &&
words->getRef(wordIndex - 1)
- ->badnessAndPenalty.lineCanBeBroken ()) {
+ ->badnessAndPenalty.lineCanBeBroken (penaltyIndex)) {
// TODO Comment the last condition (also below where the minimum is
// searched for)
newLine = true;
@@ -568,7 +582,8 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
if (breakPos == -1 ||
w->badnessAndPenalty.compareTo
- (&words->getRef(breakPos)->badnessAndPenalty) <= 0)
+ (penaltyIndex,
+ &words->getRef(breakPos)->badnessAndPenalty) <= 0)
// "<=" instead of "<" in the next lines tends to result in
// more words per line -- theoretically. Practically, the
// case "==" will never occur.
@@ -592,7 +607,8 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
BadnessAndPenalty correctedBap = lastWord->badnessAndPenalty;
correctedBap.setPenalty (0);
if (correctedBap.compareTo
- (&words->getRef(breakPos)->badnessAndPenalty) <= 0) {
+ (penaltyIndex,
+ &words->getRef(breakPos)->badnessAndPenalty) <= 0) {
breakPos = searchUntil;
PRINTF (" corrected: breakPos = %d\n", breakPos);
}
@@ -605,7 +621,7 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
PRINTF ("\n");
if (word1->badnessAndPenalty.lineTight () &&
- word1->canBeHyphenated &&
+ (word1->flags & Word::CAN_BE_HYPHENATED) &&
word1->style->x_lang[0] &&
word1->content.type == core::Content::TEXT &&
Hyphenator::isHyphenationCandidate (word1->content.text))
@@ -614,7 +630,7 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
if (word1->badnessAndPenalty.lineLoose () &&
breakPos + 1 < words->size ()) {
Word *word2 = words->getRef(breakPos + 1);
- if (word2->canBeHyphenated &&
+ if ((word2->flags & Word::CAN_BE_HYPHENATED) &&
word2->style->x_lang[0] &&
word2->content.type == core::Content::TEXT &&
Hyphenator::isHyphenationCandidate (word2->content.text))
@@ -631,6 +647,7 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
tempNewLine ? "temporally" : "permanently",
firstIndex, breakPos);
lineAdded = true;
+ penaltyIndex = calcPenaltyIndexForNewLine ();
} else {
// TODO hyphenateWord() should return whether something has
// changed at all. So that a second run, with
@@ -735,9 +752,15 @@ int Textblock::hyphenateWord (int wordIndex)
// Note: there are numBreaks + 1 word parts.
if (i < numBreaks) {
// TODO There should be a method fillHyphen.
- w->badnessAndPenalty.setPenalty (HYPHEN_BREAK);
+ w->badnessAndPenalty.setPenalties (penalties[PENALTY_HYPHEN][0],
+ penalties[PENALTY_HYPHEN][1]);
+ // "\xe2\x80\x90" is an unconditional hyphen.
w->hyphenWidth =
- layout->textWidth (origWord.style->font, "\xc2\xad", 2);
+ layout->textWidth (w->style->font, hyphenDrawChar,
+ strlen (hyphenDrawChar));
+ w->flags |= (Word::DRAW_AS_ONE_TEXT | Word::DIV_CHAR_AT_EOL |
+ Word::UNBREAKABLE_FOR_MIN_WIDTH);
+
PRINTF (" [%d] + hyphen\n", wordIndex + i);
} else {
if (origWord.content.space) {
@@ -765,9 +788,8 @@ int Textblock::hyphenateWord (int wordIndex)
origWord.spaceStyle->unref ();
free (breakPos);
- } else {
- words->getRef(wordIndex)->canBeHyphenated = false;
- }
+ } else
+ words->getRef(wordIndex)->flags &= ~Word::CAN_BE_HYPHENATED;
return numBreaks;
}
diff --git a/dw/ui.hh b/dw/ui.hh
index 0873217f..e6d98670 100644
--- a/dw/ui.hh
+++ b/dw/ui.hh
@@ -421,6 +421,7 @@ class SelectionResource: public Resource
{
public:
virtual void addItem (const char *str, bool enabled, bool selected) = 0;
+ virtual void setItem (int index, bool selected) = 0;
virtual void pushGroup (const char *name, bool enabled) = 0;
virtual void popGroup () = 0;
@@ -480,7 +481,8 @@ public:
class EntryResource: public TextResource
{
public:
- enum { UNLIMITED_MAX_LENGTH = -1 };
+ enum { UNLIMITED_SIZE = -1 };
+ virtual void setMaxLength (int maxlen) = 0;
};
class MultiLineTextResource: public TextResource
@@ -540,7 +542,7 @@ public:
virtual ListResource *createListResource (ListResource::SelectionMode
selectionMode, int rows) = 0;
virtual OptionMenuResource *createOptionMenuResource () = 0;
- virtual EntryResource *createEntryResource (int maxLength, bool password,
+ virtual EntryResource *createEntryResource (int size, bool password,
const char *label) = 0;
virtual MultiLineTextResource *createMultiLineTextResource (int cols,
int rows) = 0;
diff --git a/dw/widget.cc b/dw/widget.cc
index 4b50f05a..7d9f0bbc 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -111,7 +111,8 @@ void Widget::setParent (Widget *parent)
notifySetParent();
//DBG_OBJ_ASSOC (widget, parent);
- //printf ("%p becomes a child of %p\n", this, parent);
+ //printf ("The %s %p becomes a child of the %s %p\n",
+ // getClassName(), this, parent->getClassName(), parent);
}
void Widget::queueDrawArea (int x, int y, int width, int height)
diff --git a/dw/widget.hh b/dw/widget.hh
index e18344c7..b50269cf 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -203,7 +203,7 @@ protected:
inline void setCursor (style::Cursor cursor)
{ layout->setCursor (cursor); }
-
+#if 0
inline bool selectionButtonPress (Iterator *it, int charPos, int linkNo,
EventButton *event, bool withinContent)
{ return layout->selectionState.buttonPress (it, charPos, linkNo, event); }
@@ -215,7 +215,7 @@ protected:
inline bool selectionButtonMotion (Iterator *it, int charPos, int linkNo,
EventMotion *event, bool withinContent)
{ return layout->selectionState.buttonMotion (it, charPos, linkNo, event); }
-
+#endif
inline bool selectionHandleEvent (SelectionState::EventType eventType,
Iterator *it, int charPos, int linkNo,
MousePositionEvent *event)
diff --git a/src/capi.c b/src/capi.c
index 1da2d9ca..0d7e79a4 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -302,7 +302,11 @@ static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
/* Let's be kind and make the HTTP query string for the dpi */
char *proxy_connect = a_Http_make_connect_str(web->url);
Dstr *http_query = a_Http_make_query_str(web->url, web->requester,FALSE);
- /* BUG: embedded NULLs in query data will truncate message */
+
+ if ((uint_t) http_query->len > strlen(http_query->str)) {
+ /* Can't handle NULLs embedded in query data */
+ MSG_ERR("HTTPS query truncated!\n");
+ }
/* BUG: WORKAROUND: request to only check the root URL's certificate.
* This avoids the dialog bombing that stems from loading multiple
diff --git a/src/decode.c b/src/decode.c
index 7ea3dc25..c5752e62 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -242,24 +242,6 @@ Decode *a_Decode_content_init(const char *format)
}
/*
- * Legal names for the ASCII character set
- */
-static int Decode_is_ascii(const char *str)
-{
- return (!(dStrAsciiCasecmp(str, "ASCII") &&
- dStrAsciiCasecmp(str, "US-ASCII") &&
- dStrAsciiCasecmp(str, "us") &&
- dStrAsciiCasecmp(str, "IBM367") &&
- dStrAsciiCasecmp(str, "cp367") &&
- dStrAsciiCasecmp(str, "csASCII") &&
- dStrAsciiCasecmp(str, "ANSI_X3.4-1968") &&
- dStrAsciiCasecmp(str, "iso-ir-6") &&
- dStrAsciiCasecmp(str, "ANSI_X3.4-1986") &&
- dStrAsciiCasecmp(str, "ISO_646.irv:1991") &&
- dStrAsciiCasecmp(str, "ISO646-US")));
-}
-
-/*
* Initialize decoder to translate from any character set known to iconv()
* to UTF-8.
*
@@ -272,8 +254,7 @@ Decode *a_Decode_charset_init(const char *format)
if (format &&
strlen(format) &&
- dStrAsciiCasecmp(format,"UTF-8") &&
- !Decode_is_ascii(format)) {
+ dStrAsciiCasecmp(format,"UTF-8")) {
iconv_t ic = iconv_open("UTF-8", format);
if (ic != (iconv_t) -1) {
diff --git a/src/dialog.cc b/src/dialog.cc
index 1b8fd2db..6a8fd071 100644
--- a/src/dialog.cc
+++ b/src/dialog.cc
@@ -13,6 +13,7 @@
#include <math.h> // for rint()
+#include <FL/fl_ask.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Return_Button.H>
diff --git a/src/dillo.cc b/src/dillo.cc
index 173ac036..9bab589c 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -50,6 +50,7 @@
#include "auth.h"
#include "dw/fltkcore.hh"
+#include "dw/textblock.hh"
/*
* Command line options structure
@@ -359,6 +360,9 @@ int main(int argc, char **argv)
a_Cookies_init();
a_Auth_init();
+ dw::Textblock::setPenaltyHyphen (prefs.penalty_hyphen);
+ dw::Textblock::setPenaltyHyphen2 (prefs.penalty_hyphen_2);
+
/* command line options override preferences */
if (options_got & DILLO_CLI_FULLWINDOW)
prefs.fullwindow_start = TRUE;
diff --git a/src/domain.c b/src/domain.c
index af8c8075..90d6b414 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -132,17 +132,17 @@ bool_t a_Domain_permit(const DilloUrl *source, const DilloUrl *dest)
if (a_Url_same_organization(source, dest))
return TRUE;
+ ret = default_deny ? FALSE : TRUE;
+
for (i = 0; i < num_exceptions; i++) {
- if(Domain_match(source_host, exceptions[i].origin) &&
- Domain_match(dest_host, exceptions[i].destination)) {
+ if (Domain_match(source_host, exceptions[i].origin) &&
+ Domain_match(dest_host, exceptions[i].destination)) {
ret = default_deny;
MSG("Domain: Matched rule from %s to %s.\n", exceptions[i].origin,
exceptions[i].destination);
break;
}
}
- if (i == num_exceptions)
- ret = default_deny ? FALSE : TRUE;
MSG("Domain: %s from %s to %s.\n",
(ret == TRUE ? "permitted" : "DENIED"), source_host, dest_host);
diff --git a/src/form.cc b/src/form.cc
index 11f27b47..05042569 100644
--- a/src/form.cc
+++ b/src/form.cc
@@ -177,6 +177,7 @@ public:
void addOption (char *value, bool selected, bool enabled);
void ensureSelection ();
void addOptionsTo (SelectionResource *res);
+ void reset (SelectionResource *res);
void appendValuesTo (Dlist *values, SelectionResource *res);
};
@@ -360,7 +361,7 @@ void Html_tag_open_form(DilloHtml *html, const char *tag, int tagsize)
a_Url_free(action);
}
-void Html_tag_close_form(DilloHtml *html, int TagIdx)
+void Html_tag_close_form(DilloHtml *html)
{
// DilloHtmlForm *form;
// int i;
@@ -547,10 +548,11 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
if (a_Html_get_attr(html, tag, tagsize, "readonly"))
((EntryResource *) resource)->setEditable(false);
-// /* Maximum length of the text in the entry */
-// if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "maxlength")))
-// gtk_entry_set_max_length(GTK_ENTRY(widget),
-// strtol(attrbuf, NULL, 10));
+ /* Maximum length of the text in the entry */
+ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "maxlength"))) {
+ int maxlen = strtol(attrbuf, NULL, 10);
+ ((EntryResource *) resource)->setMaxLength(maxlen);
+ }
}
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
@@ -680,7 +682,7 @@ void Html_tag_content_textarea(DilloHtml *html, const char *tag, int tagsize)
* Close textarea
* (TEXTAREA is parsed in VERBATIM mode, and entities are handled here)
*/
-void Html_tag_close_textarea(DilloHtml *html, int TagIdx)
+void Html_tag_close_textarea(DilloHtml *html)
{
char *str;
DilloHtmlInput *input;
@@ -750,11 +752,12 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize)
type = DILLO_HTML_INPUT_SELECT;
res = factory->createOptionMenuResource ();
} else {
+ ListResource::SelectionMode mode;
+
type = DILLO_HTML_INPUT_SEL_LIST;
- res = factory->createListResource (multi ?
- ListResource::SELECTION_MULTIPLE :
- ListResource::SELECTION_EXACTLY_ONE,
- rows);
+ mode = multi ? ListResource::SELECTION_MULTIPLE
+ : ListResource::SELECTION_AT_MOST_ONE;
+ res = factory->createListResource (mode, rows);
}
Embed *embed = new Embed(res);
@@ -774,7 +777,7 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize)
/*
* ?
*/
-void Html_tag_close_select(DilloHtml *html, int TagIdx)
+void Html_tag_close_select(DilloHtml *html)
{
if (html->InFlags & IN_SELECT) {
if (html->InFlags & IN_OPTION)
@@ -785,9 +788,10 @@ void Html_tag_close_select(DilloHtml *html, int TagIdx)
DilloHtmlInput *input = Html_get_current_input(html);
DilloHtmlSelect *select = input->select;
- // BUG(?): should not do this for MULTI selections
- select->ensureSelection ();
-
+ if (input->type == DILLO_HTML_INPUT_SELECT) {
+ // option menu interface requires that something be selected */
+ select->ensureSelection ();
+ }
SelectionResource *res = (SelectionResource*)input->embed->getResource();
select->addOptionsTo (res);
}
@@ -868,7 +872,7 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->setNonCssHint (PROPERTY_X_TOOLTIP, CSS_TYPE_STRING,
attrbuf);
}
- /* We used to have Textblock (prefs.limit_text_width) here,
+ /* We used to have Textblock (prefs.limit_text_width, ...) here,
* but it caused 100% CPU usage.
*/
page = new Textblock (false);
@@ -898,7 +902,7 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize)
/*
* Handle close <BUTTON>
*/
-void Html_tag_close_button(DilloHtml *html, int TagIdx)
+void Html_tag_close_button(DilloHtml *html)
{
html->InFlags &= ~IN_BUTTON;
}
@@ -982,8 +986,6 @@ void DilloHtmlForm::submit(DilloHtmlInput *active_input, EventButton *event)
}
a_Url_free(url);
}
- // /* now, make the rendered area have its focus back */
- // gtk_widget_grab_focus(GTK_BIN(bw->render_main_scroll)->child);
}
/*
@@ -1764,35 +1766,12 @@ void DilloHtmlInput::reset ()
}
break;
case DILLO_HTML_INPUT_SELECT:
+ case DILLO_HTML_INPUT_SEL_LIST:
if (select != NULL) {
- /* this is in reverse order so that, in case more than one was
- * selected, we get the last one, which is consistent with handling
- * of multiple selected options in the layout code. */
-// for (i = select->num_options - 1; i >= 0; i--) {
-// if (select->options[i].init_val) {
-// gtk_menu_item_activate(GTK_MENU_ITEM
-// (select->options[i].menuitem));
-// Html_select_set_history(input);
-// break;
-// }
-// }
+ SelectionResource *sr = (SelectionResource *) embed->getResource();
+ select->reset(sr);
}
break;
- case DILLO_HTML_INPUT_SEL_LIST:
- if (!select)
- break;
-// for (i = 0; i < select->num_options; i++) {
-// if (select->options[i].init_val) {
-// if (select->options[i].menuitem->state == GTK_STATE_NORMAL)
-// gtk_list_select_child(GTK_LIST(select->menu),
-// select->options[i].menuitem);
-// } else {
-// if (select->options[i].menuitem->state==GTK_STATE_SELECTED)
-// gtk_list_unselect_child(GTK_LIST(select->menu),
-// select->options[i].menuitem);
-// }
-// }
- break;
case DILLO_HTML_INPUT_TEXTAREA:
if (init_str != NULL) {
MultiLineTextResource *textres =
@@ -1874,6 +1853,15 @@ void DilloHtmlSelect::addOptionsTo (SelectionResource *res)
}
}
+void DilloHtmlSelect::reset (SelectionResource *res)
+{
+ int size = options->size ();
+ for (int i = 0; i < size; i++) {
+ DilloHtmlOption *option = options->get (i);
+ res->setItem(i, option->selected);
+ }
+}
+
void DilloHtmlSelect::appendValuesTo (Dlist *values, SelectionResource *res)
{
int size = options->size ();
diff --git a/src/form.hh b/src/form.hh
index cd04543f..297442e0 100644
--- a/src/form.hh
+++ b/src/form.hh
@@ -48,16 +48,16 @@ void a_Html_form_display_hiddens2(void *v_form, bool display);
*/
void Html_tag_open_form(DilloHtml *html, const char *tag, int tagsize);
-void Html_tag_close_form(DilloHtml *html, int TagIdx);
+void Html_tag_close_form(DilloHtml *html);
void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize);
void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize);
void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize);
void Html_tag_content_textarea(DilloHtml *html, const char *tag, int tagsize);
-void Html_tag_close_textarea(DilloHtml *html, int TagIdx);
+void Html_tag_close_textarea(DilloHtml *html);
void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize);
-void Html_tag_close_select(DilloHtml *html, int TagIdx);
+void Html_tag_close_select(DilloHtml *html);
void Html_tag_open_option(DilloHtml *html, const char *tag, int tagsize);
void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize);
-void Html_tag_close_button(DilloHtml *html, int TagIdx);
+void Html_tag_close_button(DilloHtml *html);
#endif /* __FORM_HH__ */
diff --git a/src/html.cc b/src/html.cc
index ea675c1a..f1936f03 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -69,7 +69,7 @@ using namespace dw::core::style;
*---------------------------------------------------------------------------*/
class DilloHtml;
typedef void (*TagOpenFunct) (DilloHtml *html, const char *tag, int tagsize);
-typedef void (*TagCloseFunct) (DilloHtml *html, int TagIdx);
+typedef void (*TagCloseFunct) (DilloHtml *html);
typedef enum {
SEEK_ATTR_START,
@@ -460,7 +460,7 @@ void DilloHtml::initDw()
dReturn_if_fail (dw == NULL);
/* Create the main widget */
- dw = stack->getRef(0)->textblock = new Textblock (prefs.limit_text_width);
+ dw = stack->getRef(0)->textblock = new Textblock (prefs.limit_text_width);
bw->num_page_bugs = 0;
dStr_truncate(bw->page_bugs, 0);
@@ -1307,7 +1307,7 @@ static void Html_tag_cleanup_to_idx(DilloHtml *html, int idx)
BUG_MSG(" - forcing close of open tag: <%s>\n", toptag.name);
_MSG("Close: %*s%s\n", size," ", toptag.name);
if (toptag.close)
- toptag.close(html, toptag_idx);
+ toptag.close(html);
Html_real_pop_tag(html);
}
}
@@ -1573,7 +1573,7 @@ static void Html_tag_open_html(DilloHtml *html, const char *tag, int tagsize)
/*
* Handle close HTML element
*/
-static void Html_tag_close_html(DilloHtml *html, int TagIdx)
+static void Html_tag_close_html(DilloHtml *html)
{
/* TODO: may add some checks here */
if (html->Num_HTML == 1) {
@@ -1608,7 +1608,7 @@ static void Html_tag_open_head(DilloHtml *html, const char *tag, int tagsize)
* twice when the head element is closed implicitly.
* Note2: HEAD is parsed once completely got.
*/
-static void Html_tag_close_head(DilloHtml *html, int TagIdx)
+static void Html_tag_close_head(DilloHtml *html)
{
if (html->InFlags & IN_HEAD) {
_MSG("Closing HEAD section\n");
@@ -1638,7 +1638,7 @@ static void Html_tag_open_title(DilloHtml *html, const char *tag, int tagsize)
* Handle close TITLE
* set page-title in the browser window and in the history.
*/
-static void Html_tag_close_title(DilloHtml *html, int TagIdx)
+static void Html_tag_close_title(DilloHtml *html)
{
if (html->InFlags & IN_HEAD) {
/* title is only valid inside HEAD */
@@ -1663,7 +1663,7 @@ static void Html_tag_open_script(DilloHtml *html, const char *tag, int tagsize)
/*
* Handle close SCRIPT
*/
-static void Html_tag_close_script(DilloHtml *html, int TagIdx)
+static void Html_tag_close_script(DilloHtml *html)
{
/* eventually the stash will be sent to an interpreter for parsing */
}
@@ -1700,7 +1700,7 @@ static void Html_tag_open_style(DilloHtml *html, const char *tag, int tagsize)
/*
* Handle close STYLE
*/
-static void Html_tag_close_style(DilloHtml *html, int TagIdx)
+static void Html_tag_close_style(DilloHtml *html)
{
if (prefs.parse_embedded_css && html->loadCssFromStash)
html->styleEngine->parse(html, NULL, html->Stash->str, html->Stash->len,
@@ -1790,7 +1790,7 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
/*
* BODY
*/
-static void Html_tag_close_body(DilloHtml *html, int TagIdx)
+static void Html_tag_close_body(DilloHtml *html)
{
if (html->Num_BODY == 1) {
/* some tag soup pages use multiple BODY tags... */
@@ -2226,7 +2226,7 @@ static void Html_tag_content_map(DilloHtml *html, const char *tag, int tagsize)
/*
* Handle close <MAP>
*/
-static void Html_tag_close_map(DilloHtml *html, int TagIdx)
+static void Html_tag_close_map(DilloHtml *html)
{
/* This is a hack for the perhaps frivolous feature of drawing image map
* shapes when there is no image to display. If this map is defined after
@@ -2497,7 +2497,7 @@ static void Html_tag_open_a(DilloHtml *html, const char *tag, int tagsize)
/*
* <A> close function
*/
-static void Html_tag_close_a(DilloHtml *html, int TagIdx)
+static void Html_tag_close_a(DilloHtml *html)
{
html->InVisitedLink = false;
}
@@ -2529,7 +2529,7 @@ static void Html_tag_open_q(DilloHtml *html, const char *tag, int tagsize)
/*
* </Q>
*/
-static void Html_tag_close_q(DilloHtml *html, int TagIdx)
+static void Html_tag_close_q(DilloHtml *html)
{
/* Right Double Quotation Mark */
const char *U201D = "\xe2\x80\x9d";
@@ -2659,7 +2659,7 @@ static void Html_tag_open_li(DilloHtml *html, const char *tag, int tagsize)
/*
* Close <LI>
*/
-static void Html_tag_close_li(DilloHtml *html, int TagIdx)
+static void Html_tag_close_li(DilloHtml *html)
{
html->InFlags &= ~IN_LI;
((ListItem *)html->dw)->flush ();
@@ -2771,7 +2771,7 @@ static void Html_tag_open_pre(DilloHtml *html, const char *tag, int tagsize)
/*
* Custom close for <PRE>
*/
-static void Html_tag_close_pre(DilloHtml *html, int TagIdx)
+static void Html_tag_close_pre(DilloHtml *html)
{
html->InFlags &= ~IN_PRE;
}
@@ -3025,22 +3025,6 @@ static void Html_tag_open_link(DilloHtml *html, const char *tag, int tagsize)
}
/*
- * Set the history of the menu to be consistent with the active menuitem.
- */
-//static void Html_select_set_history(DilloHtmlInput *input)
-//{
-// int i;
-//
-// for (i = 0; i < input->select->num_options; i++) {
-// if (GTK_CHECK_MENU_ITEM(input->select->options[i].menuitem)->active) {
-// gtk_option_menu_set_history(GTK_OPTION_MENU(input->widget), i);
-// break;
-// }
-// }
-//}
-
-
-/*
* Set the Document Base URI
*/
static void Html_tag_open_base(DilloHtml *html, const char *tag, int tagsize)
@@ -3109,7 +3093,7 @@ static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize)
/*
* Default close for paragraph tags - pop the stack and break.
*/
-static void Html_tag_close_par(DilloHtml *html, int TagIdx)
+static void Html_tag_close_par(DilloHtml *html)
{
HT2TB(html)->addParbreak (9, html->styleEngine->wordStyle ());
}
diff --git a/src/prefs.c b/src/prefs.c
index a7fa1bcf..88d10a8d 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -101,6 +101,12 @@ void a_Prefs_init(void)
prefs.start_page = a_Url_new(PREFS_START_PAGE, NULL);
prefs.theme = dStrdup(PREFS_THEME);
prefs.w3c_plus_heuristics = TRUE;
+
+ prefs.penalty_hyphen = 100;
+ prefs.penalty_hyphen_2 = 100;
+ prefs.penalty_em_dash_left = 800;
+ prefs.penalty_em_dash_right = 100;
+ prefs.penalty_em_dash_right_2 = 800;
}
/*
diff --git a/src/prefs.h b/src/prefs.h
index 7622aea3..0c392ae5 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -89,6 +89,8 @@ struct _DilloPrefs {
bool_t show_msg;
bool_t show_extra_warnings;
bool_t middle_click_drags_page;
+ int penalty_hyphen, penalty_hyphen_2;
+ int penalty_em_dash_left, penalty_em_dash_right, penalty_em_dash_right_2;
};
/* Global Data */
diff --git a/src/prefsparser.cc b/src/prefsparser.cc
index aa810b1e..6eb8c11d 100644
--- a/src/prefsparser.cc
+++ b/src/prefsparser.cc
@@ -12,6 +12,8 @@
#include <sys/types.h>
#include <stdlib.h>
#include <locale.h> /* for setlocale */
+#include <math.h> /* for isinf */
+#include <limits.h>
#include "prefs.h"
#include "misc.h"
@@ -28,6 +30,7 @@ typedef enum {
PREFS_URL,
PREFS_INT32,
PREFS_DOUBLE,
+ PREFS_FRACTION_100,
PREFS_GEOMETRY,
PREFS_PANEL_SIZE
} PrefType_t;
@@ -107,7 +110,15 @@ int PrefsParser::parseOption(char *name, char *value)
{ "small_icons", &prefs.small_icons, PREFS_BOOL },
{ "start_page", &prefs.start_page, PREFS_URL },
{ "theme", &prefs.theme, PREFS_STRING },
- { "w3c_plus_heuristics", &prefs.w3c_plus_heuristics, PREFS_BOOL }
+ { "w3c_plus_heuristics", &prefs.w3c_plus_heuristics, PREFS_BOOL },
+ { "penalty_hyphen", &prefs.penalty_hyphen, PREFS_FRACTION_100 },
+ { "penalty_hyphen_2", &prefs.penalty_hyphen_2, PREFS_FRACTION_100 },
+ { "penalty_em_dash_left", &prefs.penalty_em_dash_left,
+ PREFS_FRACTION_100 },
+ { "penalty_em_dash_right", &prefs.penalty_em_dash_right,
+ PREFS_FRACTION_100 },
+ { "penalty_em_dash_right_2", &prefs.penalty_em_dash_right_2,
+ PREFS_FRACTION_100 }
};
node = NULL;
@@ -160,6 +171,18 @@ int PrefsParser::parseOption(char *name, char *value)
case PREFS_DOUBLE:
*(double *)node->pref = strtod(value, NULL);
break;
+ case PREFS_FRACTION_100:
+ {
+ double d = strtod (value, NULL);
+ if (isinf(d)) {
+ if (d > 0)
+ *(int*)node->pref = INT_MAX;
+ else
+ *(int*)node->pref = INT_MIN;
+ } else
+ *(int*)node->pref = 100 * d;
+ }
+ break;
case PREFS_GEOMETRY:
a_Misc_parse_geometry(value, &prefs.xpos, &prefs.ypos,
&prefs.width, &prefs.height);
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 48092c23..8aa8cdc3 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -51,7 +51,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
style_attrs.color = Color::create (layout, 0);
style_attrs.backgroundColor = Color::create (layout, 0xffffff);
- n->style = Style::create (layout, &style_attrs);
+ n->style = Style::create (&style_attrs);
}
StyleEngine::~StyleEngine () {
@@ -718,7 +718,7 @@ Style * StyleEngine::backgroundStyle () {
assert (attrs.backgroundColor);
stack->getRef (stack->size () - 1)->backgroundStyle =
- Style::create (layout, &attrs);
+ Style::create (&attrs);
}
return stack->getRef (stack->size () - 1)->backgroundStyle;
}
@@ -760,7 +760,7 @@ Style * StyleEngine::style0 (int i) {
postprocessAttrs (&attrs);
- stack->getRef (i)->style = Style::create (layout, &attrs);
+ stack->getRef (i)->style = Style::create (&attrs);
return stack->getRef (i)->style;
}
@@ -774,7 +774,7 @@ Style * StyleEngine::wordStyle0 () {
attrs.valign = style ()->valign;
- stack->getRef(stack->size() - 1)->wordStyle = Style::create(layout, &attrs);
+ stack->getRef(stack->size() - 1)->wordStyle = Style::create(&attrs);
return stack->getRef (stack->size () - 1)->wordStyle;
}
diff --git a/src/table.cc b/src/table.cc
index 98157e76..41f2b686 100644
--- a/src/table.cc
+++ b/src/table.cc
@@ -297,7 +297,7 @@ static void Html_set_collapsing_border_model(DilloHtml *html, Widget *col_tb)
collapseCellAttrs.borderWidth.bottom = borderWidth;
collapseCellAttrs.hBorderSpacing = 0;
collapseCellAttrs.vBorderSpacing = 0;
- collapseStyle = Style::create(HT2LT(html), &collapseCellAttrs);
+ collapseStyle = Style::create(&collapseCellAttrs);
col_tb->setStyle (collapseStyle);
if (Html_table_get_border_model(html) != DILLO_HTML_TABLE_BORDER_COLLAPSE) {
@@ -314,7 +314,7 @@ static void Html_set_collapsing_border_model(DilloHtml *html, Widget *col_tb)
collapseTableAttrs.borderStyle = collapseCellAttrs.borderStyle;
/* CSS2 17.6.2: table does not have padding (in collapsing mode) */
collapseTableAttrs.padding.setVal (0);
- collapseStyle = Style::create(HT2LT(html), &collapseTableAttrs);
+ collapseStyle = Style::create(&collapseTableAttrs);
((dw::Table*)S_TOP(html)->table)->setStyle (collapseStyle);
}
}
@@ -331,7 +331,7 @@ static void Html_set_separate_border_model(DilloHtml *html, Widget *col_tb)
separateCellAttrs = *(html->styleEngine->style ());
/* CSS2 17.5: Internal table elements do not have margins */
separateCellAttrs.margin.setVal (0);
- separateStyle = Style::create(HT2LT(html), &separateCellAttrs);
+ separateStyle = Style::create(&separateCellAttrs);
col_tb->setStyle (separateStyle);
}
diff --git a/test/dw_anchors_test.cc b/test/dw_anchors_test.cc
index cb839f40..d7201053 100644
--- a/test/dw_anchors_test.cc
+++ b/test/dw_anchors_test.cc
@@ -130,20 +130,20 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (5);
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- topWidgetStyle = Style::create (layout, &styleAttrs);
+ topWidgetStyle = Style::create (&styleAttrs);
styleAttrs.margin.left = 20;
styleAttrs.margin.right = 0;
styleAttrs.backgroundColor = NULL;
- widgetStyle = Style::create (layout, &styleAttrs);
+ widgetStyle = Style::create (&styleAttrs);
styleAttrs.margin.left = 0;
- wordStyle = Style::create (layout, &styleAttrs);
+ wordStyle = Style::create (&styleAttrs);
fontAttrs.size = 28;
fontAttrs.weight = 700;
styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs);
- headingStyle = Style::create (layout, &styleAttrs);
+ headingStyle = Style::create (&styleAttrs);
Fl::add_timeout (0, textTimeout, NULL);
diff --git a/test/dw_border_test.cc b/test/dw_border_test.cc
index 988abc33..ec5a09a5 100644
--- a/test/dw_border_test.cc
+++ b/test/dw_border_test.cc
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle1 = Style::create (layout, &styleAttrs);
+ Style *widgetStyle1 = Style::create (&styleAttrs);
styleAttrs.backgroundColor = Color::create (layout, 0xffff80);
styleAttrs.margin.setVal (0);
@@ -74,7 +74,7 @@ int main(int argc, char **argv)
styleAttrs.setBorderStyle (BORDER_SOLID);
styleAttrs.padding.setVal (1);
- Style *widgetStyle2 = Style::create (layout, &styleAttrs);
+ Style *widgetStyle2 = Style::create (&styleAttrs);
Textblock *textblock1 = new Textblock (false);
textblock1->setStyle (widgetStyle1);
@@ -87,7 +87,7 @@ int main(int argc, char **argv)
styleAttrs.backgroundColor = NULL;
styleAttrs.cursor = CURSOR_TEXT;
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
const char *words1[] = { "Some", "random", "text.", NULL };
const char *words2[] = { "A", "nested", "paragraph.", NULL };
diff --git a/test/dw_example.cc b/test/dw_example.cc
index 52aa2440..259650cf 100644
--- a/test/dw_example.cc
+++ b/test/dw_example.cc
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
dw::core::style::Color::create (layout, 0xffffff);
dw::core::style::Style *widgetStyle =
- dw::core::style::Style::create (layout, &styleAttrs);
+ dw::core::style::Style::create (&styleAttrs);
dw::Textblock *textblock = new dw::Textblock (false);
textblock->setStyle (widgetStyle);
@@ -72,7 +72,7 @@ int main(int argc, char **argv)
styleAttrs.backgroundColor = NULL;
dw::core::style::Style *wordStyle =
- dw::core::style::Style::create (layout, &styleAttrs);
+ dw::core::style::Style::create (&styleAttrs);
for(int i = 1; i <= 10; i++) {
char buf[4];
diff --git a/test/dw_find_test.cc b/test/dw_find_test.cc
index e5c79fd3..5bddda10 100644
--- a/test/dw_find_test.cc
+++ b/test/dw_find_test.cc
@@ -107,15 +107,15 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (10);
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *topWidgetStyle = Style::create (layout, &styleAttrs);
+ Style *topWidgetStyle = Style::create (&styleAttrs);
styleAttrs.margin.setVal (0);
styleAttrs.margin.left = 30;
styleAttrs.backgroundColor = NULL;
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
styleAttrs.margin.left = 0;
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (topWidgetStyle);
diff --git a/test/dw_float_test.cc b/test/dw_float_test.cc
index 11d04984..70273e89 100644
--- a/test/dw_float_test.cc
+++ b/test/dw_float_test.cc
@@ -58,18 +58,18 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
styleAttrs.borderWidth.setVal (1);
styleAttrs.setBorderColor (Color::create (layout, 0x808080));
styleAttrs.setBorderStyle (BORDER_DASHED);
styleAttrs.width = createAbsLength(100);
styleAttrs.vloat = FLOAT_LEFT;
- Style *leftFloatStyle = Style::create (layout, &styleAttrs);
+ Style *leftFloatStyle = Style::create (&styleAttrs);
styleAttrs.width = createAbsLength(80);
styleAttrs.vloat = FLOAT_RIGHT;
- Style *rightFloatStyle = Style::create (layout, &styleAttrs);
+ Style *rightFloatStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -83,7 +83,7 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (0);
styleAttrs.backgroundColor = NULL;
- wordStyle = Style::create (layout, &styleAttrs);
+ wordStyle = Style::create (&styleAttrs);
for(int i = 1; i <= 10; i++) {
char buf[16];
diff --git a/test/dw_images_scaled.cc b/test/dw_images_scaled.cc
index 2f8896e6..34a72c21 100644
--- a/test/dw_images_scaled.cc
+++ b/test/dw_images_scaled.cc
@@ -120,7 +120,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -131,7 +131,7 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (0);
styleAttrs.backgroundColor = NULL;
- Style *imageStyle = Style::create (layout, &styleAttrs);
+ Style *imageStyle = Style::create (&styleAttrs);
image = new dw::Image ("");
textblock->addWidget (image, imageStyle);
diff --git a/test/dw_images_scaled2.cc b/test/dw_images_scaled2.cc
index 2adb1770..81cdd2e8 100644
--- a/test/dw_images_scaled2.cc
+++ b/test/dw_images_scaled2.cc
@@ -95,7 +95,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -108,7 +108,7 @@ int main(int argc, char **argv)
styleAttrs.padding.setVal (0);
styleAttrs.backgroundColor = NULL;
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
styleAttrs.borderWidth.setVal (1);
styleAttrs.setBorderColor (Color::create (layout, 0x000080));
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
styleAttrs.width = createPerLength (0.25);
styleAttrs.height = createPerLength (0.25);
- Style *imageStyle1 = Style::create (layout, &styleAttrs);
+ Style *imageStyle1 = Style::create (&styleAttrs);
image1 = new dw::Image ("A longer ALT Text to demonstrate clipping.");
textblock->addWidget (image1, imageStyle1);
imageStyle1->unref();
@@ -128,7 +128,7 @@ int main(int argc, char **argv)
styleAttrs.width = LENGTH_AUTO;
styleAttrs.height = LENGTH_AUTO;
- Style *imageStyle2 = Style::create (layout, &styleAttrs);
+ Style *imageStyle2 = Style::create (&styleAttrs);
image2 = new dw::Image ("A longer ALT Text to demonstrate clipping.");
textblock->addWidget (image2, imageStyle2);
imageStyle2->unref();
diff --git a/test/dw_images_simple.cc b/test/dw_images_simple.cc
index 8f00f847..34de20ea 100644
--- a/test/dw_images_simple.cc
+++ b/test/dw_images_simple.cc
@@ -119,7 +119,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -130,7 +130,7 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (0);
styleAttrs.backgroundColor = NULL;
- Style *imageStyle = Style::create (layout, &styleAttrs);
+ Style *imageStyle = Style::create (&styleAttrs);
image = new dw::Image ("");
textblock->addWidget (image, imageStyle);
diff --git a/test/dw_links.cc b/test/dw_links.cc
index 5622cbd5..79ccbb54 100644
--- a/test/dw_links.cc
+++ b/test/dw_links.cc
@@ -99,7 +99,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -113,7 +113,7 @@ int main(int argc, char **argv)
styleAttrs.backgroundColor = NULL;
styleAttrs.cursor = CURSOR_TEXT;
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
styleAttrs.color = Color::create (layout, 0x0000ff);
styleAttrs.textDecoration = TEXT_DECORATION_UNDERLINE;
@@ -137,7 +137,7 @@ int main(int argc, char **argv)
}
styleAttrs.x_link = i;
- Style *linkStyle = Style::create (layout, &styleAttrs);
+ Style *linkStyle = Style::create (&styleAttrs);
for(int j = 0; words2[j]; j++) {
textblock->addText(words2[j], linkStyle);
diff --git a/test/dw_links2.cc b/test/dw_links2.cc
index b8e8c55b..acb095f3 100644
--- a/test/dw_links2.cc
+++ b/test/dw_links2.cc
@@ -128,7 +128,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -142,7 +142,7 @@ int main(int argc, char **argv)
styleAttrs.backgroundColor = NULL;
styleAttrs.cursor = CURSOR_TEXT;
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
styleAttrs.color = Color::create (layout, 0x0000ff);
styleAttrs.textDecoration = TEXT_DECORATION_UNDERLINE;
@@ -166,7 +166,7 @@ int main(int argc, char **argv)
}
styleAttrs.x_link = i;
- Style *linkStyle = Style::create (layout, &styleAttrs);
+ Style *linkStyle = Style::create (&styleAttrs);
for(int j = 0; words2[j]; j++) {
textblock->addText (words2[j], linkStyle);
diff --git a/test/dw_lists.cc b/test/dw_lists.cc
index 12fa1627..2aa0abb7 100644
--- a/test/dw_lists.cc
+++ b/test/dw_lists.cc
@@ -61,7 +61,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -73,7 +73,7 @@ int main(int argc, char **argv)
styleAttrs.backgroundColor = NULL;
styleAttrs.cursor = CURSOR_TEXT;
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
styleAttrs.margin.setVal (5);
styleAttrs.padding.setVal (5);
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
styleAttrs.setBorderStyle (BORDER_SOLID);
styleAttrs.borderWidth.setVal (1);
- Style *itemStyle = Style::create (layout, &styleAttrs);
+ Style *itemStyle = Style::create (&styleAttrs);
const char *wordsPar[] = {
"This", "is", "a", "normal", "paragraph.", "And",
diff --git a/test/dw_resource_test.cc b/test/dw_resource_test.cc
index a2a26c62..e8a8b227 100644
--- a/test/dw_resource_test.cc
+++ b/test/dw_resource_test.cc
@@ -62,7 +62,7 @@ int main(int argc, char **argv)
styleAttrs.color = Color::create (layout, 0x000000);
styleAttrs.backgroundColor = Color::create (layout, 0xffffff);
- Style *widgetStyle = Style::create (layout, &styleAttrs);
+ Style *widgetStyle = Style::create (&styleAttrs);
Textblock *textblock = new Textblock (false);
textblock->setStyle (widgetStyle);
@@ -73,7 +73,7 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (0);
styleAttrs.backgroundColor = NULL;
- widgetStyle = Style::create (layout, &styleAttrs);
+ widgetStyle = Style::create (&styleAttrs);
SelectionResource *res = layout->getResourceFactory()->createListResource
(ListResource::SELECTION_AT_MOST_ONE, 4);
diff --git a/test/dw_table.cc b/test/dw_table.cc
index 75842e60..5416d05b 100644
--- a/test/dw_table.cc
+++ b/test/dw_table.cc
@@ -66,7 +66,7 @@ int main(int argc, char **argv)
fontAttrs.fontVariant = FONT_VARIANT_NORMAL;
styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs);
- Style *tableStyle = Style::create (layout, &styleAttrs);
+ Style *tableStyle = Style::create (&styleAttrs);
Table *table = new Table (false);
table->setStyle (tableStyle);
@@ -79,14 +79,14 @@ int main(int argc, char **argv)
styleAttrs.margin.setVal (0);
styleAttrs.padding.setVal (5);
- Style *cellStyle = Style::create (layout, &styleAttrs);
+ Style *cellStyle = Style::create (&styleAttrs);
styleAttrs.borderWidth.setVal (0);
styleAttrs.margin.setVal (0);
styleAttrs.cursor = CURSOR_TEXT;
styleAttrs.textAlignChar = '.';
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
for (int i = 0; i < 4; i++) {
table->addRow (wordStyle);
diff --git a/test/dw_table_aligned.cc b/test/dw_table_aligned.cc
index 022e7026..96cb0602 100644
--- a/test/dw_table_aligned.cc
+++ b/test/dw_table_aligned.cc
@@ -66,7 +66,7 @@ int main(int argc, char **argv)
styleAttrs.hBorderSpacing = 5;
styleAttrs.vBorderSpacing = 5;
- Style *tableStyle = Style::create (layout, &styleAttrs);
+ Style *tableStyle = Style::create (&styleAttrs);
Table *table = new Table (false);
table->setStyle (tableStyle);
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
styleAttrs.borderWidth.setVal (1);
styleAttrs.setBorderStyle (BORDER_INSET);
- Style *cellStyle = Style::create (layout, &styleAttrs);
+ Style *cellStyle = Style::create (&styleAttrs);
styleAttrs.borderWidth.setVal (0);
styleAttrs.margin.setVal (0);
@@ -85,7 +85,7 @@ int main(int argc, char **argv)
styleAttrs.cursor = CURSOR_TEXT;
styleAttrs.textAlignChar = '.';
- Style *wordStyle = Style::create (layout, &styleAttrs);
+ Style *wordStyle = Style::create (&styleAttrs);
TableCell *ref = NULL;
for(int i = 0; i < 10; i++) {
diff --git a/test/dw_ui_test.cc b/test/dw_ui_test.cc
index 60893f06..2bcee1c5 100644
--- a/test/dw_ui_test.cc
+++ b/test/dw_ui_test.cc
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
fontAttrs.fontVariant = FONT_VARIANT_NORMAL;
styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs);
- Style *tableStyle = Style::create (layout, &styleAttrs);
+ Style *tableStyle = Style::create (&styleAttrs);
Table *table = new Table (false);
table->setStyle (tableStyle);
@@ -76,7 +76,7 @@ int main(int argc, char **argv)
styleAttrs.backgroundColor = NULL;
styleAttrs.margin.setVal (0);
- Style *cellStyle = Style::create (layout, &styleAttrs);
+ Style *cellStyle = Style::create (&styleAttrs);
// First of all, the resources. Later, they are embedded into the
// widget tree.
diff --git a/test/hyphens-etc.html b/test/hyphens-etc.html
new file mode 100644
index 00000000..cbc55b79
--- /dev/null
+++ b/test/hyphens-etc.html
@@ -0,0 +1,6 @@
+<p>Abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde&shy;abcde</p>
+<p>Abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde-abcde</p>
+<p>Abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde&#x2010;abcde</p>
+<p>Abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde&mdash;abcde</p>
+<p lang="de">Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen&mdash;Nordrhein-Westfalen</p>
+<p lang="de">Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen&mdash;Nord&shy;rheinwestfalen</p>