Okay -- I've attached the single function I modified (GetLineMetrics,
in paragraph.c).  I have commented the portions I modified.  Please let
me know if it does cause any problems -- I would really like to see this
added.  The only potential problem I can see is if the hyphen character
is the first character in a word (ie, a unary negative).  I haven't
completely thought through how the code will behave in that case.

On another note -- I've noticed that ALIGNMENT_JUSTIFY does not work in
every case; i.e., in some instances, a line will not be justified, but
the preceding and following lines will be.  Is this a known bug, or
should I investigate it further?  (I've noticed it in the CVS snapshot I
downloaded today.)

Thanks for the excellent program!

- Jamis


On Sun, 2002-04-28 at 19:44, David A. Desrosiers wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> 
> > I'm brand new to this list, however, and couldn't find any appropriate
> > documentation on the plucker website, so: what is the best way to submit
> > this change, and does it need to go through some kind of review?
> 
>       Send it to the list as an attachment (if large) or paste the patch
> (via diff -u) into the body of the message, or simply describe how you fixed
> it, and one of us (likely Bill Janssen) will pick it up and test and commit
> it if it seems to solve the problem in a way that doesn't break other
> things.
> 
> 
> d.
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.0.6 (GNU/Linux)
> Comment: For info see http://www.gnupg.org
> 
> iD8DBQE8zKWYkRQERnB1rkoRAvc5AJ915DcYkerTtnPMsjX0w14/QYs9bgCgntrx
> nKh+1c+3RcMQMz6hzFMWXCg=
> =04oM
> -----END PGP SIGNATURE-----
> 
-- 
Jamis Buck
[EMAIL PROTECTED]
http://hippa-potta.jamisandtarasine.net
.
"I'd horsewhip you if I had a horse." -- Groucho Marx
/* Return the number of characters that will fit in a line */
static void GetLineMetrics
    (
    ParagraphContext*   pContext,           /* pointer to paragraph context */
    Boolean             skipLeadingSpace,   /* true if initial non-visible 
                                               characters should be skipped */
    Int16*              length,             /* upon return, set to number of 
                                               characters that will fit in the 
                                               line */
    Int16*              height              /* upon return, set to the height 
                                               of the line */
    )
{
    Char*   startPosition;
    Boolean lastSpaceIsVisible;
    FontID  initialFontStyle;
    Int16   initialLeftMargin;
    Int16   initialRightMargin;
    Int16   tokenCount;
    Int16   lastSpace;
    Int16   linePixels;
    Int16   lastSpacePixels;
    Int16   lastSpaceHeight;
    Int16   charWidth;
    /* added 28 Apr 2002 by Jamis Buck ([EMAIL PROTECTED]) */
    UInt8   adjacentDashes;
    /* --------------------------- */

    startPosition       = pContext->position;
    initialFontStyle    = FntGetFont();
    initialLeftMargin   = pContext->left;
    initialRightMargin  = pContext->right;

    addMarginToCurrent = true;

    *height     = 0;
    tokenCount  = 0;

    spaceCount          = 0;
    lastSpace           = 0;
    linePixels          = 0;
    lastSpacePixels     = 0;
    lastSpaceHeight     = 0;
    lastSpaceIsVisible  = false;

    /* added 28 Apr 2002 by Jamis Buck ([EMAIL PROTECTED]) */
    adjacentDashes      = 0;
    /* --------------------------- */

    for ( ;; ) {
        Char        nextToken;
        TokenType   nextTokenType;

        nextTokenType = GetNextToken( pContext, &nextToken );

        if ( nextTokenType == TOKEN_PARAGRAPH_END )
            break;
        else if ( nextTokenType == TOKEN_FUNCTION ) {
            HandleFunction( pContext, NULL, &charWidth );

            tokenCount++;
            if ( newLine ) {
                newLine = false;
                break;
            }
            if ( horizontalRule ) {
                horizontalRule  = false;
                linePixels     += charWidth;
                *height         = pContext->fontHeight;
                break;
            }
            if ( image ) {
                image               = false;
                skipLeadingSpace    = false;
                if ( ( ( linePixels + charWidth ) <= pContext->maxPixels ) || 
                     linePixels == 0 ) {
                    if ( *height < pContext->fontHeight )
                        *height = pContext->fontHeight;
                    lastSpaceIsVisible  = false;
                    lastSpacePixels     = linePixels;
                    lastSpaceHeight     = *height;
                    lastSpace           = tokenCount;
                }
                else {
                    tokenCount--;
                    break;
                }
            }
            linePixels += charWidth;
            if ( pContext->maxPixels < linePixels )
                break;

            continue;
        }
        addMarginToCurrent = false;

        if ( skipLeadingSpace && CharIsSpace( nextToken ) && ! FixedWidthFont() )
            continue;

        skipLeadingSpace = false;

        /* Count the spaces, leading ones are skipped above */
        if ( nextToken == ' ' ) {
            spaceCount++;
            lastSpaceIsVisible  = true;
            lastSpacePixels     = linePixels;
            lastSpaceHeight     = *height;
            lastSpace           = tokenCount;

        /* added 28 Apr 2002 by Jamis Buck ([EMAIL PROTECTED]) */
        /* the idea here is to treat multiple adjacent hyphenation characters as if they were
         * a single long hyphen.  If the line needs to wrap in the middle of this hyphen, we
         * instead wrap on the "lastSpace" character. Note that we're looking for four
         * different types of hyphens:
         *   ASCII 0x2D '-'  : the standard ASCII dash, or minus, character
         *   ASCII 0x96 '-'  : ISO Latin 1 'n-dash' character
         *   ASCII 0x97 '--' : ISO Latin 1 'm-dash' character
         *   ASCII 0xAD '�'  : in the HTML 4.0 list of character entities, this is the 'soft'
         *                     or 'discretionary' hyphen.
         * TODO: are there more types of hyphens and/or word-break characters we should be looking for? */
        } else if( nextToken == '-' || nextToken == '\xAD' || nextToken == '\x96' || nextToken == '\x97' ) {
          adjacentDashes++;

        } else if( adjacentDashes > 0 ) {
          lastSpacePixels = linePixels;
          adjacentDashes = 0;
          lastSpace = tokenCount;
        }
        /* --------------------------- */

        charWidth = FntCharWidth( nextToken );

        if ( pContext->maxPixels < ( charWidth + linePixels ) ) {
            if ( ( pContext->maxPixels / 2 ) < lastSpacePixels ) {
                if ( lastSpaceIsVisible )
                    spaceCount--;
                tokenCount  = lastSpace;
                linePixels  = lastSpacePixels;
                *height     = lastSpaceHeight;

            /* added 28 Apr 2002 by Jamis Buck ([EMAIL PROTECTED]) */
            /* if adjacentDashes is greater than 0, then we're in the middle of a series
             * of adjacent hyphens, and we wrap instead of the previous space character. */
            } else if( adjacentDashes > 0 ) {
              tokenCount = lastSpace;
              linePixels = lastSpacePixels;
              *height = lastSpaceHeight;
            }
            /* --------------------------- */

            break;
        }
        linePixels += charWidth;

        if ( *height < FntLineHeight() )
            *height = pContext->fontHeight = FntLineHeight();

        tokenCount++;
    }
    if ( pContext->fontHeight != *height )
        pContext->fontHeight = *height;

    pContext->position      = startPosition;
    pContext->linePixels    = linePixels;
    *length                 = tokenCount;
    pContext->maxPixels    += ( initialLeftMargin - pContext->left ) + 
                              ( initialRightMargin - pContext->right );

    /* Restore font style and margins */
    FntSetFont( initialFontStyle );
    pContext->left  = initialLeftMargin;
    pContext->right = initialRightMargin;
}


Reply via email to