aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsgeerken <devnull@localhost>2012-09-05 20:22:16 +0200
committersgeerken <devnull@localhost>2012-09-05 20:22:16 +0200
commit97c5cff6bcc41c2ac1239ba25c9f7ab34e16e6ba (patch)
tree3ec981ca4f17750bff732a5b8a1109c9c16c8386
parent60e562a0bb7329c6f6e9d66faad567cf660b01a4 (diff)
More cleanup.
-rw-r--r--dw/textblock.hh30
-rw-r--r--dw/textblock_linebreaking.cc86
2 files changed, 48 insertions, 68 deletions
diff --git a/dw/textblock.hh b/dw/textblock.hh
index eb6dfddd..d70721a0 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -155,7 +155,8 @@ private:
class BadnessAndPenalty
{
private:
- enum { TOO_LOOSE, QUITE_LOOSE, BADNESS_VALUE, TOO_TIGHT } badnessState;
+ 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;
@@ -163,12 +164,27 @@ private:
// for debugging:
int totalWidth, idealWidth, totalStretchability, totalShrinkability;
- int badnessInffinities ();
- int penaltyInffinities ();
- int badnessInfinities ();
- int penaltyInfinities ();
- int badnessValue ();
- int penaltyValue ();
+ // "Infinity levels" are used to represent very large numbers,
+ // including "quasi-infinite" numbers. A couple of infinity
+ // level and number can be mathematically represented as
+ //
+ // number * N ^ (infinity level)
+ //
+ // where N is a number which is large enough. Practically,
+ // infinity levels are used to circumvent limited ranges for
+ // integer numbers.
+
+ // Here, all infinity levels have got special meanings.
+ enum {
+ INF_VALUE = 0, // simple values
+ INF_LARGE, // large values, like QUITE_LOOSE
+ INF_NOT_STRETCHABLE, // reserved for NOT_STRECTHABLE
+ INF_INFINITE, // "really" infinite
+ INF_MAX = INF_INFINITE
+ };
+
+ int badnessValue (int infLevel);
+ int penaltyValue (int infLevel);
public:
void calcBadness (int totalWidth, int idealWidth,
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index f2175803..80e41945 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -10,16 +10,20 @@ using namespace lout;
namespace dw {
-int Textblock::BadnessAndPenalty::badnessInffinities ()
+int Textblock::BadnessAndPenalty::badnessValue (int infLevel)
{
switch (badnessState) {
- case TOO_LOOSE:
- case TOO_TIGHT:
- return 1;
+ case NOT_STRETCHABLE:
+ return infLevel == INF_NOT_STRETCHABLE ? 1 : 0;
case QUITE_LOOSE:
+ return infLevel == INF_LARGE ? 1 : 0;
+
case BADNESS_VALUE:
- return 0;
+ return infLevel == INF_VALUE ? badness : 0;
+
+ case TOO_TIGHT:
+ return infLevel == INF_INFINITE ? 1 : 0;
}
// compiler happiness
@@ -27,17 +31,17 @@ int Textblock::BadnessAndPenalty::badnessInffinities ()
return 0;
}
-int Textblock::BadnessAndPenalty::penaltyInffinities ()
+int Textblock::BadnessAndPenalty::penaltyValue (int infLevel)
{
switch (penaltyState) {
case FORCE_BREAK:
- return -1;
+ return infLevel == INF_INFINITE ? -1 : 0;
case PROHIBIT_BREAK:
- return 1;
+ return infLevel == INF_INFINITE ? 1 : 0;
case PENALTY_VALUE:
- return 0;
+ return infLevel == INF_VALUE ? penalty : 0;
}
// compiler happiness
@@ -45,26 +49,6 @@ int Textblock::BadnessAndPenalty::penaltyInffinities ()
return 0;
}
-int Textblock::BadnessAndPenalty::badnessInfinities ()
-{
- return badnessState == QUITE_LOOSE ? ratio : 0;
-}
-
-int Textblock::BadnessAndPenalty::penaltyInfinities ()
-{
- return 0;
-}
-
-int Textblock::BadnessAndPenalty::badnessValue ()
-{
- return badnessState == BADNESS_VALUE ? badness : 0;
-}
-
-int Textblock::BadnessAndPenalty::penaltyValue ()
-{
- return penaltyState == PENALTY_VALUE ? penalty : 0;
-}
-
void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
int totalStretchability,
int totalShrinkability)
@@ -81,7 +65,7 @@ void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth,
badness = 0;
} else if (totalWidth < idealWidth) {
if (totalStretchability == 0)
- badnessState = TOO_LOOSE;
+ badnessState = NOT_STRETCHABLE;
else {
ratio = 100 * (idealWidth - totalWidth) / totalStretchability;
if (ratio > 1024)
@@ -126,7 +110,7 @@ void Textblock::BadnessAndPenalty::setPenaltyForceBreak ()
bool Textblock::BadnessAndPenalty::lineLoose ()
{
return
- badnessState == TOO_LOOSE || badnessState == QUITE_LOOSE ||
+ badnessState == NOT_STRETCHABLE || badnessState == QUITE_LOOSE ||
(badnessState == BADNESS_VALUE && ratio > 0);
}
@@ -154,42 +138,22 @@ bool Textblock::BadnessAndPenalty::lineCanBeBroken ()
int Textblock::BadnessAndPenalty::compareTo (BadnessAndPenalty *other)
{
- // First, a special condition: if a line is too tight, it will
- // always be regarded as worse than a line, which is not too
- // tight. Especially, lines too tight are worse than lines too
- // loose. See test/table-1.html as a text case: the first line,
- // which contains only the word "Short,", is too loose, but not
- // breaking here would make the line too tight, making the text
- // overwrap the available space.
-
- if (lineTooTight() && !other->lineTooTight())
- return 1;
- if (!lineTooTight() && other->lineTooTight())
- return -1;
-
- int thisNumInffinities = badnessInffinities () + penaltyInffinities ();
- int otherNumInffinities =
- other->badnessInffinities () + other->penaltyInffinities ();
- int thisNumInfinities = badnessInfinities () + penaltyInfinities ();
- int otherNumInfinities =
- other->badnessInfinities () + other->penaltyInfinities ();
- int thisValue = badnessValue () + penaltyValue ();
- int otherValue = other->badnessValue () + other->penaltyValue ();
-
- if (thisNumInffinities == otherNumInffinities) {
- if (thisNumInfinities == otherNumInfinities)
+ for (int l = INF_MAX; l >= 0; l--) {
+ int thisValue = badnessValue (l) + penaltyValue (l);
+ int otherValue = other->badnessValue (l) + other->penaltyValue (l);
+
+ if (thisValue != otherValue)
return thisValue - otherValue;
- else
- return thisNumInfinities - otherNumInfinities;
- } else
- return thisNumInffinities - otherNumInffinities;
+ }
+
+ return 0;
}
void Textblock::BadnessAndPenalty::print ()
{
switch (badnessState) {
- case TOO_LOOSE:
- printf ("too loose");
+ case NOT_STRETCHABLE:
+ printf ("not stretchable");
break;
case TOO_TIGHT: