patch: display/print smart quotes


Subject: patch: display/print smart quotes
From: WJCarpenter (bill-abisource@carpenter.ORG)
Date: Fri Jun 30 2000 - 13:14:16 CDT


The attached family of patches implements the display and printing of
alternative glyphs for smart quotes and other "invisible" characters.
The patch is a diff against the nightly sources of 063000 vintage.
(Sorry, I couldn't do the CVS diff described recently, but where I
have high-speed access, I have a firewall that blocks me.)

This set of patches fixes bugs:

#812 [CRASH] abiword dumps core when attempting to print (Linux/i386)
#757 Curly quotes imorted from MSWord cause words to be marked
     mis-spelled (there was an open item about displaying glyphs)
#764 apostrophe error in word97 imports in version 0.7.8

I have split the patches up into XP and per-platform chunks, all of
which should be committed together. Alas, I can only test on Linux.
In fact, it is possible that simple typos on my part could prevent
compilation on other platforms. Because I have modified some classes
in the XP area, I think anyone who wants to build this will have to
apply the XP patch and the appropriate per-platform patch (and, as
usual, "make clean"). I am reasonably confident that if a given
per-platform patch compiles, it will work properly (see waffle words
below). I just don't want to end up breaking builds on platforms
where I can't personally iterate. Perhaps folks who have development
environments for Win32, BeOS, QNX, and Mac can try these patches and
report success/failure? (Actually, since the whole per-platform GUI
interface code for Mac looks vacant, I'm not sure what the heck is
going on there. Does that thing even build/run?)

The general idea of this patch is to display "something" for otherwise
invisible characters in a document. Scratch replacements are done by
the XP function GR_Graphics::remapGlyph() when a character/string is
drawn via per-platform drawChar() or drawChars(), or measured via
per-platform measureString(). (Well, OK, I have made a new
per-platform function measureUnRemappedChar() and created an XP
measureString() defined in terms of that.) Both printing and display
use those functions for rendering (if some platform uses something
else on the sly, I probably didn't catch it). The characters that
appear in the document itself are not changed, so no special action is
needed for various document save/save-as functions, and cut-and-paste
preserves any smart quotes or other "invisible" characters.

Both double smart quote characters (UCS_RDBLQUOTE, UCS_LDBLQUOTE) are
replaced with ASCII double quote. Left single smart quote
(UCS_LQUOTE) is replaced with ASCII back quote, and right single smart
quote (UCS_RQUOTE) is replaced with ASCII single quote. (Those
special replacements are done only when the glyph would otherwise be
"invisible".) Any other "invisible" character (defined as a character
with zero width) is mapped to the Latin-1 "degree circle" (character
0xB0). TODO: Create configuration options and accompanying dialog
boxes to enable/disable invisible character glyph remapping, and to
specify what the replacement characters are. TODO: create a dialog
box that lets a user turn on/off smart quoting algorithm for newly
typed text, and a way to sweep through a document to smart quote or
un-smart quote existing text.

On some platforms (BeOS, Win32, QNX), the glyph remapping isn't
actually done all the time after this patch. It's not a hard thing to
do, but as I can't compile/test the changes, I would prefer to work
with developers who are on those platforms and guide them in the
simple change needed to make it work, the sooner the better. (The
situation in a nutshell is that the per-platform drawChars() on those
platforms uses the array of Unicode characters from the document
directly as an argument to a rendering call. The simple fix is to
make a local copy first and use that, doing the remapGlyph() as the
copy is being made. I have left a TODO in the code where this needs
to happen.)

-- 
bill@carpenter.ORG (WJCarpenter)    PGP 0x91865119
38 95 1B 69 C9 C6 3D 25    73 46 32 04 69 D6 ED F3

diff -c -r abi-063000/src/af/gr/xp/gr_Graphics.cpp abi-063000-new/src/af/gr/xp/gr_Graphics.cpp *** abi-063000/src/af/gr/xp/gr_Graphics.cpp Sun Jun 18 18:53:51 2000 --- abi-063000-new/src/af/gr/xp/gr_Graphics.cpp Fri Jun 30 00:55:38 2000 *************** *** 25,30 **** --- 25,31 ---- #include "ut_assert.h" #include "ut_string.h" #include "ut_units.h" + #include "ut_debugmsg.h" GR_Font::GR_Font() { *************** *** 68,73 **** --- 69,129 ---- return MaxWidth; + } + + UT_uint32 GR_Graphics::measureString(const UT_UCSChar* s, int iOffset, + int num, unsigned short* pWidths) + { + // Generic base class version defined in terms of measureUnRemappedChar(). + // Platform versions can roll their own if it makes a performance difference. + UT_ASSERT(s); + + int charWidth = 0, width; + + for (int i = 0; i < num; i++) + { + UT_UCSChar currentChar = s[i + iOffset]; + + width = measureUnRemappedChar(currentChar); + if (width == 0) + { + xxx_UT_DEBUGMSG(("GR_Graphics::measureString remapping 0x%04X\n", currentChar)); + currentChar = remapGlyph(currentChar, UT_TRUE); + width = measureUnRemappedChar(currentChar); + } + + charWidth += width; + if (pWidths) + pWidths[i] = width; + } + + return charWidth; + } + + UT_UCSChar GR_Graphics::remapGlyph(const UT_UCSChar actual, UT_Bool noMatterWhat) + { + // This routine is for remapping zero-width characters, which + // represent undefined glyphs in the font, into something useful + // and visible. This is most useful for the smart quote + // characters, which are specially treated. Other zero-width + // characters are mapped to a generic filler character. + UT_UCSChar remap = actual; + unsigned short w = 1; + + w = measureUnRemappedChar(actual); + if (noMatterWhat || w == 0) + { + switch (actual) + { + case UCS_LQUOTE: remap = '`'; break; + case UCS_RQUOTE: remap = '\''; break; + case UCS_RDBLQUOTE: remap = '"'; break; + case UCS_LDBLQUOTE: remap = '"'; break; + default: remap = (w ? actual : 0xB0); break; + } + } + if (remap != actual) UT_DEBUGMSG(("remapGlyph 0x%04X -> 0x%04X %d %d\n", actual, remap, noMatterWhat, w)); + return remap; } void GR_Graphics::setZoomPercentage(UT_uint32 iZoom) diff -c -r abi-063000/src/af/gr/xp/gr_Graphics.h abi-063000-new/src/af/gr/xp/gr_Graphics.h *** abi-063000/src/af/gr/xp/gr_Graphics.h Sun Jun 18 18:53:51 2000 --- abi-063000-new/src/af/gr/xp/gr_Graphics.h Thu Jun 29 17:13:20 2000 *************** *** 73,79 **** virtual UT_uint32 getFontDescent() = 0; virtual UT_uint32 getFontHeight() = 0; ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths) = 0; UT_uint32 getMaxCharacterWidth(const UT_UCSChar*s, UT_uint32 Length); --- 73,82 ---- virtual UT_uint32 getFontDescent() = 0; virtual UT_uint32 getFontHeight() = 0; ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c) = 0; ! ! UT_UCSChar remapGlyph(const UT_UCSChar actual, UT_Bool noMatterWhat); UT_uint32 getMaxCharacterWidth(const UT_UCSChar*s, UT_uint32 Length);

diff -c -r abi-063000/src/af/gr/unix/gr_UnixGraphics.cpp abi-063000-new/src/af/gr/unix/gr_UnixGraphics.cpp *** abi-063000/src/af/gr/unix/gr_UnixGraphics.cpp Tue Jun 20 20:55:56 2000 --- abi-063000-new/src/af/gr/unix/gr_UnixGraphics.cpp Fri Jun 30 00:59:23 2000 *************** *** 95,101 **** // HACK: I need more speed void GR_UnixGraphics::drawChar(UT_UCSChar Char, UT_sint32 xoff, UT_sint32 yoff) { ! GdkWChar Wide_char = Char; GdkFont *font = m_pFont->getGdkFont(); gdk_draw_text_wc (m_pWin, font, m_pGC, --- 95,101 ---- // HACK: I need more speed void GR_UnixGraphics::drawChar(UT_UCSChar Char, UT_sint32 xoff, UT_sint32 yoff) { ! GdkWChar Wide_char = remapGlyph(Char, UT_FALSE); GdkFont *font = m_pFont->getGdkFont(); gdk_draw_text_wc (m_pWin, font, m_pGC, *************** *** 122,128 **** for (int i = 0; i < iLength; i++) { ! pNChars[i] = pChars[i + iCharOffset]; } --- 122,128 ---- for (int i = 0; i < iLength; i++) { ! pNChars[i] = remapGlyph(pChars[i + iCharOffset], UT_FALSE); } *************** *** 139,145 **** // the vast majority of calls to this function are // to draw a single character, so we'll optimize this case ! GdkWChar pChar = pChars[iCharOffset]; gdk_draw_text_wc (m_pWin, font, m_pGC, xoff, yoff + font->ascent, &pChar, 1); } --- 139,145 ---- // the vast majority of calls to this function are // to draw a single character, so we'll optimize this case ! GdkWChar pChar = remapGlyph(pChars[iCharOffset], UT_FALSE); gdk_draw_text_wc (m_pWin, font, m_pGC, xoff, yoff + font->ascent, &pChar, 1); } *************** *** 185,190 **** --- 185,210 ---- return font->ascent + font->descent; } + UT_uint32 GR_UnixGraphics::measureUnRemappedChar(const UT_UCSChar c) + { + // measureString() could be defined in terms of measureUnRemappedChar() + // but its not (for presumed performance reasons). Also, a difference + // is that measureString() uses remapping to get past zero-width + // character cells. + if (!m_pFontManager) + return 0; + + UT_ASSERT(m_pFont); + UT_ASSERT(m_pGC); + + int width; + GdkWChar cChar = c; + + GdkFont* pFont = m_pFont->getGdkFont(); + width = gdk_text_width_wc (pFont, &cChar, 1); + return width; + } + #if 0 UT_uint32 GR_UnixGraphics::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { *************** *** 212,217 **** --- 232,242 ---- cChar = s[i + iOffset]; width = gdk_text_width_wc (pFont, &cChar, 1); + if (width == 0) + { + cChar = remapGlyph(s[i + iOffset], UT_TRUE); + width = gdk_text_width_wc (pFont, &cChar, 1); + } charWidth += width; if (pWidths) *************** *** 220,226 **** return charWidth; } ! UT_uint32 GR_UnixGraphics::_getResolution(void) const { // this is hard-coded at 100 for X now, since 75 (which --- 245,251 ---- return charWidth; } ! #endif UT_uint32 GR_UnixGraphics::_getResolution(void) const { // this is hard-coded at 100 for X now, since 75 (which diff -c -r abi-063000/src/af/gr/unix/gr_UnixGraphics.h abi-063000-new/src/af/gr/unix/gr_UnixGraphics.h *** abi-063000/src/af/gr/unix/gr_UnixGraphics.h Sun Jun 18 18:53:49 2000 --- abi-063000-new/src/af/gr/unix/gr_UnixGraphics.h Thu Jun 29 23:07:53 2000 *************** *** 40,47 **** int iLength, UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, ! unsigned short* pWidths); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); --- 40,47 ---- int iLength, UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! // virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); diff -c -r abi-063000/src/af/xap/unix/xap_UnixPSGraphics.cpp abi-063000-new/src/af/xap/unix/xap_UnixPSGraphics.cpp *** abi-063000/src/af/xap/unix/xap_UnixPSGraphics.cpp Mon Jun 19 04:32:07 2000 --- abi-063000-new/src/af/xap/unix/xap_UnixPSGraphics.cpp Thu Jun 29 22:54:57 2000 *************** *** 155,160 **** --- 155,167 ---- #endif } + UT_uint32 PS_Graphics::measureUnRemappedChar(const UT_UCSChar c) + { + UT_ASSERT(m_pCurrentFont); + const UT_uint16 * cwi = m_pCurrentFont->getUniWidths(); + return (c >= 256 ? 0 : _scale(cwi[c])); + } + #if 0 UT_uint32 PS_Graphics::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { *************** *** 166,173 **** UT_uint32 iCharWidth = 0; for (int k=0; k<num; k++) { ! UT_ASSERT(p[k] < 256); // TODO deal with Unicode ! register int x = _scale(cwi[p[k]]); iCharWidth += x; pWidths[k] = x; --- 173,187 ---- UT_uint32 iCharWidth = 0; for (int k=0; k<num; k++) { ! //UT_ASSERT(p[k] < 256); // TODO deal with Unicode ! register int x; ! UT_UCSChar currentChar; ! currentChar = p[k]; ! if (currentChar >= 256 || !(_scale(cwi[currentChar]))) ! { ! currentChar = remapGlyph(currentChar, UT_TRUE); ! } ! x = _scale(cwi[currentChar]); iCharWidth += x; pWidths[k] = x; *************** *** 175,181 **** return iCharWidth; } ! UT_uint32 PS_Graphics::_getResolution(void) const { return PS_RESOLUTION; --- 189,195 ---- return iCharWidth; } ! #endif UT_uint32 PS_Graphics::_getResolution(void) const { return PS_RESOLUTION; *************** *** 313,318 **** --- 327,333 ---- const UT_UCSChar * pS = pChars+iCharOffset; const UT_UCSChar * pEnd = pS+iLength; + UT_UCSChar currentChar; *pD++ = '('; while (pS<pEnd) *************** *** 328,334 **** // TODO deal with Unicode issues. ! switch (*pS) { case 0x08: *pD++ = '\\'; *pD++ = 'b'; break; case UCS_TAB: *pD++ = '\\'; *pD++ = 't'; break; --- 343,350 ---- // TODO deal with Unicode issues. ! currentChar = remapGlyph(*pS, currentChar >= 256 ? UT_TRUE : UT_FALSE); ! switch (currentChar) { case 0x08: *pD++ = '\\'; *pD++ = 'b'; break; case UCS_TAB: *pD++ = '\\'; *pD++ = 't'; break; *************** *** 338,344 **** case '\\': *pD++ = '\\'; *pD++ = '\\'; break; case '(': *pD++ = '\\'; *pD++ = '('; break; case ')': *pD++ = '\\'; *pD++ = ')'; break; ! default: *pD++ = (unsigned char) *pS; break; } pS++; } --- 354,360 ---- case '\\': *pD++ = '\\'; *pD++ = '\\'; break; case '(': *pD++ = '\\'; *pD++ = '('; break; case ')': *pD++ = '\\'; *pD++ = ')'; break; ! default: *pD++ = (unsigned char)currentChar; break; } pS++; } diff -c -r abi-063000/src/af/xap/unix/xap_UnixPSGraphics.h abi-063000-new/src/af/xap/unix/xap_UnixPSGraphics.h *** abi-063000/src/af/xap/unix/xap_UnixPSGraphics.h Sun Jun 18 18:53:53 2000 --- abi-063000-new/src/af/xap/unix/xap_UnixPSGraphics.h Thu Jun 29 22:55:12 2000 *************** *** 55,61 **** virtual UT_uint32 getFontDescent(); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); --- 55,62 ---- virtual UT_uint32 getFontDescent(); virtual UT_uint32 getFontHeight(); ! // virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont();

diff -c -r abi-063000/src/af/gr/beos/gr_BeOSGraphics.cpp abi-063000-new/src/af/gr/beos/gr_BeOSGraphics.cpp *** abi-063000/src/af/gr/beos/gr_BeOSGraphics.cpp Sun Jun 18 20:53:10 2000 --- abi-063000-new/src/af/gr/beos/gr_BeOSGraphics.cpp Fri Jun 30 09:36:13 2000 *************** *** 199,205 **** memset(buffer, 0, 2*(iLength+1)); for (i=0; i<iLength; i++) { char * utf8char; ! utf8char = UT_encodeUTF8char(pChars[i+iCharOffset]); /* printf("GR: 0x%x -UCS2 2 UTF8-> ", pChars[i+iCharOffset]); for (int t=0; utf8char[t]; t++) { --- 199,205 ---- memset(buffer, 0, 2*(iLength+1)); for (i=0; i<iLength; i++) { char * utf8char; ! utf8char = UT_encodeUTF8char(remapGlyph(pChars[i+iCharOffset], UT_FALSE)); /* printf("GR: 0x%x -UCS2 2 UTF8-> ", pChars[i+iCharOffset]); for (int t=0; utf8char[t]; t++) { *************** *** 236,241 **** --- 236,242 ---- float fontsize=viewFont.Size(); viewFont.GetEscapements(buffer,iLength,&tempdelta,escapementArray); + // TODO: need remapGlyph() before the following function call? m_pShadowView->DrawString(UT_encodeUTF8char(pChars[0+iCharOffset]), BPoint(xoff,yoff+offset)); for (i=1; i<iLength; i++) *************** *** 246,252 **** */ widthAbiWants=(unsigned short int)ceil(escapementArray[i-1].x*fontsize); xoff+=widthAbiWants; ! m_pShadowView->DrawString(UT_encodeUTF8char(pChars[i+iCharOffset]), BPoint(xoff,yoff+offset)); } m_pShadowView->Window()->Unlock(); --- 247,253 ---- */ widthAbiWants=(unsigned short int)ceil(escapementArray[i-1].x*fontsize); xoff+=widthAbiWants; ! m_pShadowView->DrawString(UT_encodeUTF8char(remapGlyph(pChars[i+iCharOffset], UT_FALSE)), BPoint(xoff,yoff+offset)); } m_pShadowView->Window()->Unlock(); *************** *** 438,443 **** --- 439,481 ---- return((UT_uint32)(fh.descent + 0.5)); } + UT_uint32 GR_BeOSGraphics::measureUnRemappedChar(const UT_UCSChar c) + { + UT_uint32 size, i; + + //We need to convert the string from UCS2 to UTF8 before + //we use the BeOS string operations on it. + char buffer[10]; + + //Set the character, then set the length of the character + size=0; + + BFont viewFont; + BPoint *escapementArray=new BPoint[num]; + + m_pShadowView->GetFont(&viewFont); + viewFont.SetSpacing(B_BITMAP_SPACING); + if (m_pShadowView->Window()->Lock()) { + m_pShadowView->SetFont(&viewFont); + m_pShadowView->Window()->Unlock(); + } + + char * utf8char; + utf8char = UT_encodeUTF8char(c); + strcpy(buffer, utf8char); + + escapement_delta tempdelta; + tempdelta.space=0.0; + tempdelta.nonspace=0.0; + //Hope this works on UTF8 characters buffers + viewFont.GetEscapements(buffer,1,&tempdelta,escapementArray); + float fontsize=viewFont.Size(); + + size+= ceil(escapementArray[i].x *fontsize); + + return(size); + } + #if 0 UT_uint32 GR_BeOSGraphics::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { *************** *** 468,474 **** for (i=0; i<num; i++) { char * utf8char; ! utf8char = UT_encodeUTF8char(s[i+iOffset]); strcat(buffer, utf8char); } --- 506,516 ---- for (i=0; i<num; i++) { char * utf8char; ! UT_UCSChar *currentChar; ! currentChar = s[i+Offset]; ! // TODO: next line might be performance hit ! currentChar = remapGlyph(currentChar, UT_FALSE); ! utf8char = UT_encodeUTF8char(currentChar); strcat(buffer, utf8char); } *************** *** 493,499 **** delete [] buffer; return(size); } ! UT_uint32 GR_BeOSGraphics::_getResolution() const { return 72; --- 535,541 ---- delete [] buffer; return(size); } ! #endif UT_uint32 GR_BeOSGraphics::_getResolution() const { return 72; diff -c -r abi-063000/src/af/gr/beos/gr_BeOSGraphics.h abi-063000-new/src/af/gr/beos/gr_BeOSGraphics.h *** abi-063000/src/af/gr/beos/gr_BeOSGraphics.h Sun Jun 18 19:23:01 2000 --- abi-063000-new/src/af/gr/beos/gr_BeOSGraphics.h Thu Jun 29 23:34:04 2000 *************** *** 43,50 **** int iLength, UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, ! unsigned short* pWidths); virtual UT_uint32 _getResolution(void) const; virtual void setColor(UT_RGBColor& clr); virtual void setColor3D(GR_Color3D c); --- 43,50 ---- int iLength, UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! //virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c); virtual UT_uint32 _getResolution(void) const; virtual void setColor(UT_RGBColor& clr); virtual void setColor3D(GR_Color3D c);

diff -c -r abi-063000/src/af/gr/qnx/gr_QNXGraphics.cpp abi-063000-new/src/af/gr/qnx/gr_QNXGraphics.cpp *** abi-063000/src/af/gr/qnx/gr_QNXGraphics.cpp Thu Jun 22 08:07:13 2000 --- abi-063000-new/src/af/gr/qnx/gr_QNXGraphics.cpp Fri Jun 30 09:36:12 2000 *************** *** 172,178 **** int i; for (i = 0; i<iLength; i++) { ! buffer[i] = (char)pChars[i]; //Bad I know convert from UTC later } buffer[i] = '\0'; --- 172,178 ---- int i; for (i = 0; i<iLength; i++) { ! buffer[i] = (char)remapGlyph(pChars[i], UT_FALSE); //Bad I know convert from UTC later } buffer[i] = '\0'; *************** *** 215,220 **** --- 215,221 ---- PgFlush(); free(buffer); #else + // TODO: need remapGlyph() before the following function call PgDrawTextmx((char *)(&pChars[iCharOffset]), iLength*sizeof(UT_UCSChar), &pos, Pg_TEXT_WIDECHAR); *************** *** 273,278 **** --- 274,312 ---- return(MY_ABS(rect.ul.y) + MY_ABS(rect.lr.y) + 1); } + UT_uint32 GR_QNXGraphics::measureUnRemappedChar(const UT_UCSChar c) + { + if (c >= 256) return 0; // TODO: doesn't grok Unicode + const char *font; + char buffer[2]; + + if (!m_pFont || !(font = m_pFont->getFont())) { + return(0); + } + + PhRect_t rect; + int indices, penpos; + + UT_UCSChar currentChar; + buffer[0] = (char)currentChar; + buffer[1] = 0; + memset(&rect, 0, sizeof(rect)); + indices = 1; + penpos = 0; + PfExtentTextCharPositions(&rect, /* Rect extent */ + NULL, /* Position offset */ + buffer, /* Buffer to hit */ + font, /* Font buffer uses */ + &indices, /* Where to get pen pos from */ + &penpos, /* Where to store pen pos */ + 1, /* Number of indices */ + 0, /* Flags */ + 0, /* Length of buffer (use strlen) */ + 0, /* Number of characters to skip */ + NULL); /* Clipping rectangle? */ + return (penpos); + } + #if 0 UT_uint32 GR_QNXGraphics::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { *************** *** 285,291 **** } //printf("GR: Measure string font %s \n", (font) ? font : "NULL"); ! //CHANGE THIS TO MAKE IT UNICODE if (num == 1) { buffer = c; } --- 319,328 ---- } //printf("GR: Measure string font %s \n", (font) ? font : "NULL"); ! // TODO: CHANGE THIS TO MAKE IT UNICODE ! // TODO: Why is this routine doing all this jazz with allocating ! // TODO: "buffer", etc, when it's only using one character at a time ! // TODO: anyhow? Why not always use "c" or some similar scheme? if (num == 1) { buffer = c; } *************** *** 329,334 **** --- 366,390 ---- 0, /* Length of buffer (use strlen) */ 0, /* Number of characters to skip */ NULL); /* Clipping rectangle? */ + if (!penpos) + { + buffer[i] = (char)remapGlyph(s[i+iOffset], UT_TRUE); + memset(&rect, 0, sizeof(rect)); + indices = 1; + penpos = 0; + + PfExtentTextCharPositions(&rect, /* Rect extent */ + NULL, /* Position offset */ + &buffer[i], /* Buffer to hit */ + font, /* Font buffer uses */ + &indices, /* Where to get pen pos from */ + &penpos, /* Where to store pen pos */ + 1, /* Number of indices */ + 0, /* Flags */ + 0, /* Length of buffer (use strlen) */ + 0, /* Number of characters to skip */ + NULL); /* Clipping rectangle? */ + } if (pWidths) pWidths[i] = penpos; charWidth += penpos; *************** *** 344,350 **** //printf("GR: Width:%d \n", charWidth); return charWidth; } ! UT_uint32 GR_QNXGraphics::_getResolution(void) const { // this is hard-coded at 100 for X now, since 75 (which --- 400,406 ---- //printf("GR: Width:%d \n", charWidth); return charWidth; } ! #endif UT_uint32 GR_QNXGraphics::_getResolution(void) const { // this is hard-coded at 100 for X now, since 75 (which diff -c -r abi-063000/src/af/gr/qnx/gr_QNXGraphics.h abi-063000-new/src/af/gr/qnx/gr_QNXGraphics.h *** abi-063000/src/af/gr/qnx/gr_QNXGraphics.h Sun Jun 18 18:53:49 2000 --- abi-063000-new/src/af/gr/qnx/gr_QNXGraphics.h Thu Jun 29 23:34:48 2000 *************** *** 58,65 **** int iLength, UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, ! unsigned short* pWidths); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); --- 58,65 ---- int iLength, UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c); ! //virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont();

diff -c -r abi-063000/src/af/gr/win/gr_Win32Graphics.cpp abi-063000-new/src/af/gr/win/gr_Win32Graphics.cpp *** abi-063000/src/af/gr/win/gr_Win32Graphics.cpp Sun Jun 18 18:53:50 2000 --- abi-063000-new/src/af/gr/win/gr_Win32Graphics.cpp Fri Jun 30 09:38:51 2000 *************** *** 171,177 **** SetTextAlign(m_hdc, TA_LEFT | TA_TOP); SetBkMode(m_hdc, TRANSPARENT); // TODO: remember and reset? ! ExtTextOutW(m_hdc, xoff, yoff, 0, NULL, &Char, 1, NULL); } void GR_Win32Graphics::drawChars(const UT_UCSChar* pChars, --- 171,178 ---- SetTextAlign(m_hdc, TA_LEFT | TA_TOP); SetBkMode(m_hdc, TRANSPARENT); // TODO: remember and reset? ! UT_UCSChar currentChar = remapGlyph(Char, UT_FALSE); ! ExtTextOutW(m_hdc, xoff, yoff, 0, NULL, &currentChar, 1, NULL); } void GR_Win32Graphics::drawChars(const UT_UCSChar* pChars, *************** *** 184,189 **** --- 185,191 ---- SetTextAlign(m_hdc, TA_LEFT | TA_TOP); SetBkMode(m_hdc, TRANSPARENT); // TODO: remember and reset? + // TODO: need remapGlyph() before the following call ExtTextOutW(m_hdc, xoff, yoff, 0, NULL, pChars + iCharOffset, iLength, NULL); //TextOutW(m_hdc, xoff, yoff, pChars + iCharOffset, iLength); } *************** *** 217,228 **** return m_pFont->getDescent(); } UT_uint32 GR_Win32Graphics::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { UT_ASSERT(m_pFont); return m_pFont->measureString(s,iOffset,num,pWidths); } ! UT_uint32 GR_Win32Graphics::_getResolution(void) const { int result = GetDeviceCaps(m_hdc, LOGPIXELSY); // NOTE: assumes square pixels --- 219,236 ---- return m_pFont->getDescent(); } + UT_uint32 GR_Win32Graphics::measureUnRemappedChar(const UT_UCSChar c) + { + UT_ASSERT(m_pFont); + return m_pFont->measureUnRemappedChar(c); + } + #if 0 UT_uint32 GR_Win32Graphics::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { UT_ASSERT(m_pFont); return m_pFont->measureString(s,iOffset,num,pWidths); } ! #endif UT_uint32 GR_Win32Graphics::_getResolution(void) const { int result = GetDeviceCaps(m_hdc, LOGPIXELSY); // NOTE: assumes square pixels *************** *** 680,685 **** --- 688,713 ---- return; } + UT_uint32 GR_Win32Font::measureUnRemappedChar(const UT_UCSChar c) + { + int iCharWidth = 0; + int iWidth; + // try to get cached value for the width of this char. + // if that fails, force fill the cache for this char + // and then re-hit the cache. + // if that fails, the char is probably not defined in + // the font, so we substitute the default char width. + iWidth = m_cw.getWidth(c); + if (!iWidth) + { + m_cw.setCharWidthsOfRange(m_oldHDC, c, c); + iWidth = m_cw.getWidth(c); + // [[Why the default width? I think zero is better in that case?]] + if (!iWidth) iWidth = 0 /* m_defaultCharWidth */; + } + return iWidth; + } + #if 0 UT_uint32 GR_Win32Font::measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths) { UT_ASSERT(s); *************** *** 695,708 **** // and then re-hit the cache. // if that fails, the char is probably not defined in // the font, so we substitute the default char width. ! ! iWidth = m_cw.getWidth(s[i+iOffset]); if (!iWidth) { ! m_cw.setCharWidthsOfRange(m_oldHDC,s[i+iOffset],s[i+iOffset]); ! iWidth = m_cw.getWidth(s[i+iOffset]); if (!iWidth) ! iWidth = m_defaultCharWidth; } iCharWidth += iWidth; --- 723,740 ---- // and then re-hit the cache. // if that fails, the char is probably not defined in // the font, so we substitute the default char width. ! UT_UCSChar currentChar; ! currentChar = s[i + iOffset]; ! iWidth = m_cw.getWidth(currentChar); if (!iWidth) { ! m_cw.setCharWidthsOfRange(m_oldHDC,currentChar,currentChar); ! iWidth = m_cw.getWidth(currentChar); if (!iWidth) ! { ! currentChar = remapGlyph(currentChar, UT_TRUE); ! iWidth = measureUnRemappedChar(currentChar); ! } } iCharWidth += iWidth; *************** *** 712,718 **** return iCharWidth; } ! GR_Win32Font::GR_Win32Font(HFONT hFont) { m_hFont = hFont; --- 744,750 ---- return iCharWidth; } ! #endif GR_Win32Font::GR_Win32Font(HFONT hFont) { m_hFont = hFont; diff -c -r abi-063000/src/af/gr/win/gr_Win32Graphics.h abi-063000-new/src/af/gr/win/gr_Win32Graphics.h *** abi-063000/src/af/gr/win/gr_Win32Graphics.h Sun Jun 18 18:53:50 2000 --- abi-063000-new/src/af/gr/win/gr_Win32Graphics.h Thu Jun 29 23:36:14 2000 *************** *** 42,49 **** inline UT_uint32 getDescent(void) { return m_tm.tmDescent; }; inline UT_uint32 getFontHeight(void) { return m_tm.tmHeight; }; void selectFontIntoDC(HDC hdc); ! UT_uint32 measureString(const UT_UCSChar* s, int iOffset, ! int num, unsigned short* pWidths); protected: HDC m_oldHDC; --- 42,49 ---- inline UT_uint32 getDescent(void) { return m_tm.tmDescent; }; inline UT_uint32 getFontHeight(void) { return m_tm.tmHeight; }; void selectFontIntoDC(HDC hdc); ! //UT_uint32 measureString(const UT_UCSChar* s, int iOffset, int num, unsigned short* pWidths); ! UT_uint32 measureUnRemappedChar(const UT_UCSChar c); protected: HDC m_oldHDC; *************** *** 69,77 **** UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureString(const UT_UCSChar*s, ! int iOffset, int num, ! unsigned short* pWidths); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); virtual GR_Font* findFont(const char* pszFontFamily, --- 69,76 ---- UT_sint32 xoff, UT_sint32 yoff); virtual void setFont(GR_Font* pFont); virtual UT_uint32 getFontHeight(); ! //virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); virtual GR_Font* findFont(const char* pszFontFamily,

diff -c -r abi-063000/src/af/gr/mac/gr_MacGraphics.h abi-063000-new/src/af/gr/mac/gr_MacGraphics.h *** abi-063000/src/af/gr/mac/gr_MacGraphics.h Thu Mar 18 14:24:46 1999 --- abi-063000-new/src/af/gr/mac/gr_MacGraphics.h Thu Jun 29 23:34:37 2000 *************** *** 50,56 **** virtual UT_uint32 getFontDescent(); virtual UT_uint32 getFontHeight(); ! virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont(); --- 50,57 ---- virtual UT_uint32 getFontDescent(); virtual UT_uint32 getFontHeight(); ! //virtual UT_uint32 measureString(const UT_UCSChar*s, int iOffset, int num, unsigned short* pWidths); ! virtual UT_uint32 measureUnRemappedChar(const UT_UCSChar c); virtual void setColor(UT_RGBColor& clr); virtual GR_Font* getGUIFont();



This archive was generated by hypermail 2b25 : Fri Jun 30 2000 - 13:16:08 CDT