? gbpatch.diff Index: salgdi3.cxx =================================================================== RCS file: /cvs/oo/gsl/vcl/unx/source/gdi/salgdi3.cxx,v retrieving revision 1.2 diff -u -r1.2 salgdi3.cxx --- salgdi3.cxx 2000/11/03 15:10:35 1.2 +++ salgdi3.cxx 2001/01/27 10:03:40 @@ -125,50 +125,50 @@ // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #ifndef PRINTER_DUMMY -static void -FaxPhoneComment( Display* pDisplay, const sal_Unicode* pStr, USHORT nLen ) +static void +FaxPhoneComment (Display * pDisplay, const sal_Unicode * pStr, USHORT nLen) { - #define FAX_PHONE_TOKEN "@@#" - #define FAX_PHONE_TOKEN_LENGTH 3 - #define FAX_END_TOKEN "@@" - - USHORT nPos; - ByteString aPhone( pStr, nLen, gsl_getSystemTextEncoding() ); - - static ByteString aPhoneNumber; - static BOOL bIsCollecting = FALSE; - - if( ! bIsCollecting ) - { - if( ( nPos = aPhone.Search( FAX_PHONE_TOKEN ) ) != STRING_NOTFOUND ) - { - aPhone.Erase( 0, nPos + FAX_PHONE_TOKEN_LENGTH ); - bIsCollecting = TRUE; - aPhoneNumber.Erase(); - } - } - if( bIsCollecting ) - { - if( ( nPos = aPhone.Search( FAX_END_TOKEN ) ) != STRING_NOTFOUND ) - { - aPhone.Erase( nPos ); - bIsCollecting = FALSE; - } - aPhoneNumber += aPhone; - if( ! bIsCollecting ) - { - aPhone = "PhoneNumber("; - aPhone += aPhoneNumber; - aPhone += ")\n"; - XpPSComment( pDisplay, aPhone.GetBuffer() ); - aPhoneNumber = ByteString(); - } - } - if( aPhoneNumber.Len() > 1024 ) - { - bIsCollecting = FALSE; - aPhoneNumber = ByteString(); - } +#define FAX_PHONE_TOKEN "@@#" +#define FAX_PHONE_TOKEN_LENGTH 3 +#define FAX_END_TOKEN "@@" + + USHORT nPos; + ByteString aPhone (pStr, nLen, gsl_getSystemTextEncoding ()); + + static ByteString aPhoneNumber; + static BOOL bIsCollecting = FALSE; + + if (!bIsCollecting) + { + if ((nPos = aPhone.Search (FAX_PHONE_TOKEN)) != STRING_NOTFOUND) + { + aPhone.Erase (0, nPos + FAX_PHONE_TOKEN_LENGTH); + bIsCollecting = TRUE; + aPhoneNumber.Erase (); + } + } + if (bIsCollecting) + { + if ((nPos = aPhone.Search (FAX_END_TOKEN)) != STRING_NOTFOUND) + { + aPhone.Erase (nPos); + bIsCollecting = FALSE; + } + aPhoneNumber += aPhone; + if (!bIsCollecting) + { + aPhone = "PhoneNumber("; + aPhone += aPhoneNumber; + aPhone += ")\n"; + XpPSComment (pDisplay, aPhone.GetBuffer ()); + aPhoneNumber = ByteString (); + } + } + if (aPhoneNumber.Len () > 1024) + { + bIsCollecting = FALSE; + aPhoneNumber = ByteString (); + } } #endif @@ -178,229 +178,234 @@ // // ---------------------------------------------------------------------------- -XlfdStorage* -SalDisplay::GetXlfdList() +XlfdStorage * +SalDisplay::GetXlfdList () { - if ( mpFontList != NULL ) - { - return mpFontList; - } - else - { - // on a display an xlfd of *-0-0-75-75-* means this is a scalable - // bitmap font, thus it is ugly and thus to avoid. On a printer - // *-0-0-300-300-* means this is a printer resident font thus nice - // thus to prefer :-( - eDeviceT eDevice = this->IsDisplay() ? eDeviceDisplay : eDevicePrinter; - - mpFactory = new AttributeProvider( eDevice ); - mpFontList = new XlfdStorage(); - - int i, nFontCount; - const int nMaxCount = 64 * 1024 - 1; - Display *pDisplay = GetDisplay(); - char **ppFontList = XListFonts(pDisplay, "-*", nMaxCount, &nFontCount); - - // - // create a list of simple Xlfd font information - // + if (mpFontList != NULL) + { + return mpFontList; + } + else + { + // on a display an xlfd of *-0-0-75-75-* means this is a scalable + // bitmap font, thus it is ugly and thus to avoid. On a printer + // *-0-0-300-300-* means this is a printer resident font thus nice + // thus to prefer :-( + eDeviceT eDevice = this->IsDisplay ()? eDeviceDisplay : eDevicePrinter; + + mpFactory = new AttributeProvider (eDevice); + mpFontList = new XlfdStorage (); + + int i, nFontCount; + const int nMaxCount = 64 * 1024 - 1; + Display *pDisplay = GetDisplay (); + char **ppFontList = XListFonts (pDisplay, "-*", nMaxCount, &nFontCount); + + // + // create a list of simple Xlfd font information + // + + Xlfd *pXlfdList = (Xlfd *) malloc (nFontCount * sizeof (Xlfd)); + int nXlfdCount = 0; + + for (i = 0; i < nFontCount; i++) + { + if (pXlfdList[nXlfdCount].FromString (ppFontList[i], mpFactory)) + ++nXlfdCount; + } + + XFreeFontNames (ppFontList); + + // classification information is needed for sorting, classification + // of charset (i.e. iso8859-1 <-> ansi-1252) depends on wether the + // display points to a printer or to a real display. On a printer all + // iso8859-1 fonts are really capable of ansi-1252 + mpFactory->AddClassification (); + // add some pretty print description + mpFactory->AddAnnotation (); + // misc feature checking + mpFactory->TagFeature (); + + // sort according to font style + qsort (pXlfdList, nXlfdCount, sizeof (Xlfd), XlfdCompare); + + // + // create a font list with merged encoding information + // + + BitmapXlfdStorage aBitmapList; + ScalableXlfd *pScalableFont = NULL; + PrinterFontXlfd *pPrinterFont = NULL; + + int nFrom = 0; + for (i = 0; i < nXlfdCount; i++) + { + // exclude openlook glyph and cursor + Attribute *pAttr = + mpFactory->RetrieveFamily (pXlfdList[i].mnFamily); + if (pAttr-> + HasFeature (XLFD_FEATURE_OL_GLYPH | XLFD_FEATURE_OL_CURSOR)) + { + continue; + } + // exclude fonts with unknown encoding + if (pXlfdList[i].GetEncoding () == RTL_TEXTENCODING_DONTKNOW) + { + continue; + } + + Bool bSameOutline = + pXlfdList[i].SameFontoutline (pXlfdList + nFrom); + XlfdFonttype eType = pXlfdList[i].Fonttype (); + + // flush the old merged font list if the name doesn't match any more + if (!bSameOutline) + { + mpFontList->Add (pScalableFont); + pScalableFont = NULL; + mpFontList->Add (pPrinterFont); + pPrinterFont = NULL; + mpFontList->Add (&aBitmapList); + aBitmapList.Reset (); + } + + // merge the font or generate a new one + switch (eType) + { + case eTypeScalable: + + if (pScalableFont == NULL) + pScalableFont = new ScalableXlfd; + pScalableFont->AddEncoding (pXlfdList + i); + + break; + + case eTypeBitmap: + + aBitmapList.AddBitmapFont (pXlfdList + i); + + break; + + case eTypePrinterBuiltIn: + case eTypePrinterDownload: + + if (pPrinterFont == NULL) + pPrinterFont = new PrinterFontXlfd; + pPrinterFont->AddEncoding (pXlfdList + i); + + break; + + case eTypeScalableBitmap: + default: + + break; + } + + nFrom = i; + } + + // flush the merged list into the global list + mpFontList->Add (pScalableFont); + mpFontList->Add (pPrinterFont); + mpFontList->Add (&aBitmapList); + + // cleanup the list of simple font information + if (pXlfdList != NULL) + free (pXlfdList); - Xlfd *pXlfdList = (Xlfd*)malloc( nFontCount * sizeof(Xlfd) ); - int nXlfdCount = 0; - - for ( i = 0; i < nFontCount; i++ ) - { - if ( pXlfdList[ nXlfdCount ].FromString(ppFontList[i], mpFactory) ) - ++nXlfdCount; - } - - XFreeFontNames( ppFontList ); - - // classification information is needed for sorting, classification - // of charset (i.e. iso8859-1 <-> ansi-1252) depends on wether the - // display points to a printer or to a real display. On a printer all - // iso8859-1 fonts are really capable of ansi-1252 - mpFactory->AddClassification(); - // add some pretty print description - mpFactory->AddAnnotation(); - // misc feature checking - mpFactory->TagFeature(); - - // sort according to font style - qsort( pXlfdList, nXlfdCount, sizeof(Xlfd), XlfdCompare ); - - // - // create a font list with merged encoding information - // - - BitmapXlfdStorage aBitmapList; - ScalableXlfd *pScalableFont = NULL; - PrinterFontXlfd *pPrinterFont = NULL; - - int nFrom = 0; - for ( i = 0; i < nXlfdCount; i++ ) - { - // exclude openlook glyph and cursor - Attribute *pAttr = mpFactory->RetrieveFamily(pXlfdList[i].mnFamily); - if ( pAttr->HasFeature( XLFD_FEATURE_OL_GLYPH - | XLFD_FEATURE_OL_CURSOR) ) - { - continue; - } - // exclude fonts with unknown encoding - if ( pXlfdList[i].GetEncoding() == RTL_TEXTENCODING_DONTKNOW ) - { - continue; - } - - Bool bSameOutline = pXlfdList[i].SameFontoutline(pXlfdList + nFrom); - XlfdFonttype eType = pXlfdList[i].Fonttype(); - - // flush the old merged font list if the name doesn't match any more - if ( !bSameOutline ) - { - mpFontList->Add( pScalableFont ); pScalableFont = NULL; - mpFontList->Add( pPrinterFont ); pPrinterFont = NULL; - mpFontList->Add( &aBitmapList ); aBitmapList.Reset(); - } - - // merge the font or generate a new one - switch( eType ) - { - case eTypeScalable: - - if ( pScalableFont == NULL ) - pScalableFont = new ScalableXlfd; - pScalableFont->AddEncoding(pXlfdList + i); - - break; - - case eTypeBitmap: - - aBitmapList.AddBitmapFont( pXlfdList + i ); - - break; - - case eTypePrinterBuiltIn: - case eTypePrinterDownload: - - if ( pPrinterFont == NULL ) - pPrinterFont = new PrinterFontXlfd; - pPrinterFont->AddEncoding( pXlfdList + i ); - - break; - - case eTypeScalableBitmap: - default: - - break; - } - - nFrom = i; - } - - // flush the merged list into the global list - mpFontList->Add( pScalableFont ); - mpFontList->Add( pPrinterFont ); - mpFontList->Add( &aBitmapList ); - - // cleanup the list of simple font information - if ( pXlfdList != NULL ) - free( pXlfdList ); - - return mpFontList; - } + return mpFontList; + } } // --------------------------------------------------------------------------- -ExtendedFontStruct* -SalDisplay::GetFont( ExtendedXlfd *pRequestedFont, int nPixelSize ) +ExtendedFontStruct * +SalDisplay::GetFont (ExtendedXlfd * pRequestedFont, int nPixelSize) { - if( !pFontCache_ ) - { - mpCvtCache = new SalConverterCache; - pFontCache_ = new SalFontCache( 64, 64, 16 ); // ??? - } - else - { - ExtendedFontStruct *pItem; - for ( pItem = pFontCache_->First(); - pItem != NULL; - pItem = pFontCache_->Next() ) - { - if ( pItem->Match(pRequestedFont, nPixelSize) ) - { - if( pFontCache_->GetCurPos() ) - { - pFontCache_->Remove( pItem ); - pFontCache_->Insert( pItem, 0UL ); - } - return pItem; - } - } - } - - // before we expand the cache, we look for very old and unused items - if( pFontCache_->Count() >= 64 ) - { - ExtendedFontStruct *pItem; - for ( pItem = pFontCache_->Last(); - pItem != NULL; - pItem = pFontCache_->Prev() ) - { - if( 1 == pItem->GetRefCount() ) - { - pFontCache_->Remove( pItem ); - pItem->ReleaseRef(); - - if( pFontCache_->Count() < 64 ) - break; - } - } - } - - ExtendedFontStruct *pItem = new ExtendedFontStruct( GetDisplay(), - nPixelSize, pRequestedFont, mpCvtCache ); - pFontCache_->Insert( pItem, 0UL ); - pItem->AddRef(); + if (!pFontCache_) + { + mpCvtCache = new SalConverterCache; + pFontCache_ = new SalFontCache (64, 64, 16); // ??? + } + else + { + ExtendedFontStruct *pItem; + for (pItem = pFontCache_->First (); + pItem != NULL; pItem = pFontCache_->Next ()) + { + if (pItem->Match (pRequestedFont, nPixelSize)) + { + if (pFontCache_->GetCurPos ()) + { + pFontCache_->Remove (pItem); + pFontCache_->Insert (pItem, 0UL); + } + return pItem; + } + } + } + + // before we expand the cache, we look for very old and unused items + if (pFontCache_->Count () >= 64) + { + ExtendedFontStruct *pItem; + for (pItem = pFontCache_->Last (); + pItem != NULL; pItem = pFontCache_->Prev ()) + { + if (1 == pItem->GetRefCount ()) + { + pFontCache_->Remove (pItem); + pItem->ReleaseRef (); + + if (pFontCache_->Count () < 64) + break; + } + } + } + + ExtendedFontStruct *pItem = new ExtendedFontStruct (GetDisplay (), + nPixelSize, + pRequestedFont, + mpCvtCache); + pFontCache_->Insert (pItem, 0UL); + pItem->AddRef (); - return pItem; + return pItem; } // --------------------------------------------------------------------------- -void -SalDisplay::DestroyFontCache() +void +SalDisplay::DestroyFontCache () { - if( pFontCache_ ) - { - ExtendedFontStruct *pItem = pFontCache_->First(); - while( pItem ) - { - delete pItem; - pItem = pFontCache_->Next(); - } - delete pFontCache_; - } - if( mpFontList ) - { - mpFontList->Dispose(); - delete mpFontList; - } - if ( mpFactory ) - { - delete mpFactory; - } - if ( mpCvtCache ) - { - delete mpCvtCache; - } - - pFontCache_ = (SalFontCache*)NULL; - mpFontList = (XlfdStorage*)NULL; - mpFactory = (AttributeProvider*)NULL; - mpCvtCache = (SalConverterCache*)NULL; + if (pFontCache_) + { + ExtendedFontStruct *pItem = pFontCache_->First (); + while (pItem) + { + delete pItem; + pItem = pFontCache_->Next (); + } + delete pFontCache_; + } + if (mpFontList) + { + mpFontList->Dispose (); + delete mpFontList; + } + if (mpFactory) + { + delete mpFactory; + } + if (mpCvtCache) + { + delete mpCvtCache; + } + + pFontCache_ = (SalFontCache *) NULL; + mpFontList = (XlfdStorage *) NULL; + mpFactory = (AttributeProvider *) NULL; + mpCvtCache = (SalConverterCache *) NULL; } // ---------------------------------------------------------------------------- @@ -409,33 +414,33 @@ // // ---------------------------------------------------------------------------- -GC -SalGraphicsData::SelectFont() +GC SalGraphicsData::SelectFont () { - Display *pDisplay = GetXDisplay(); - - if( !pFontGC_ ) - { - XGCValues values; - values.subwindow_mode = IncludeInferiors; - values.fill_rule = EvenOddRule; // Pict import/ Gradient - values.graphics_exposures = True; - values.foreground = nTextPixel_; - - pFontGC_ = XCreateGC( pDisplay, hDrawable_, - GCSubwindowMode | GCFillRule - | GCGraphicsExposures | GCForeground, - &values ); - } + Display * + pDisplay = GetXDisplay (); - if( !bFontGC_ ) - { - XSetForeground( pDisplay, pFontGC_, nTextPixel_ ); - SetClipRegion( pFontGC_ ); - bFontGC_ = TRUE; - } + if (!pFontGC_) + { + XGCValues + values; + values.subwindow_mode = IncludeInferiors; + values.fill_rule = EvenOddRule; // Pict import/ Gradient + values.graphics_exposures = True; + values.foreground = nTextPixel_; + + pFontGC_ = XCreateGC (pDisplay, hDrawable_, + GCSubwindowMode | GCFillRule + | GCGraphicsExposures | GCForeground, &values); + } + + if (!bFontGC_) + { + XSetForeground (pDisplay, pFontGC_, nTextPixel_); + SetClipRegion (pFontGC_); + bFontGC_ = TRUE; + } - return pFontGC_; + return pFontGC_; } //-------------------------------------------------------------------------- @@ -444,527 +449,555 @@ // This routine is (and should be) called only once, the result should be // stored in some static variable -static int -GetMaxFontHeight() +static int +GetMaxFontHeight () { - #define DEFAULT_MAXFONTHEIGHT 250 +#define DEFAULT_MAXFONTHEIGHT 250 - int nMaxFontHeight = 0; + int + nMaxFontHeight = 0; - char *FontHeight = getenv ("SAL_MAXFONTHEIGHT"); - if (FontHeight) - nMaxFontHeight = atoi (FontHeight); + char * + FontHeight = getenv ("SAL_MAXFONTHEIGHT"); + if (FontHeight) + nMaxFontHeight = atoi (FontHeight); - if (nMaxFontHeight <= 0) - nMaxFontHeight = DEFAULT_MAXFONTHEIGHT; + if (nMaxFontHeight <= 0) + nMaxFontHeight = DEFAULT_MAXFONTHEIGHT; - return nMaxFontHeight; + return nMaxFontHeight; } -void -SalGraphicsData::SetFont( const ImplFontSelectData *pEntry ) +void +SalGraphicsData::SetFont (const ImplFontSelectData * pEntry) { - bFontGC_ = FALSE; - xFont_ = NULL; // ->ReleaseRef() - aScale_ = Fraction( 1, 1 ); - nFontOrientation_ = pEntry->mnOrientation; - bFontVertical_ = pEntry->mbVertical; - - if( pEntry->mpFontData && pEntry->mpFontData->mpSysData ) - { - ExtendedXlfd *pSysFont = (ExtendedXlfd*)pEntry->mpFontData->mpSysData; - static int nMaxFontHeight = GetMaxFontHeight(); - - USHORT nH, nW; - if( bWindow_ ) - { - // see BugId #44528# FontWork (-> #45038#) and as well Bug #47127# - if( pEntry->mnHeight > nMaxFontHeight ) - nH = nMaxFontHeight; - else if( pEntry->mnHeight > 2 ) - nH = pEntry->mnHeight; - else - nH = 2; - nW = 0; // pEntry->mnWidth; - } - else - { - nH = pEntry->mnHeight; - nW = pEntry->mnWidth; - } - - xFont_ = GetDisplay()->GetFont( pSysFont, nH ); - if( pEntry->mnHeight > nMaxFontHeight || pEntry->mnHeight < 2 ) - aScale_ = Fraction( pEntry->mnHeight, nH ); - } - else - { - #ifdef DEBUG - // XXX Fix me: provide a fallback for poor font installations - // we may be reach this if no font matches the GUI font - // MS Sans Serif;Geneva;Helv;WarpSans;Dialog;Lucida; ... */ - fprintf( stderr, "SalGraphicsData::SetFont: Invalid Font Selection\n" ); - #endif - } + bFontGC_ = FALSE; + xFont_ = NULL; // ->ReleaseRef() + aScale_ = Fraction (1, 1); + nFontOrientation_ = pEntry->mnOrientation; + bFontVertical_ = pEntry->mbVertical; + + if (pEntry->mpFontData && pEntry->mpFontData->mpSysData) + { + ExtendedXlfd *pSysFont = (ExtendedXlfd *) pEntry->mpFontData->mpSysData; + static int nMaxFontHeight = GetMaxFontHeight (); + + USHORT nH, nW; + if (bWindow_) + { + // see BugId #44528# FontWork (-> #45038#) and as well Bug #47127# + if (pEntry->mnHeight > nMaxFontHeight) + nH = nMaxFontHeight; + else if (pEntry->mnHeight > 2) + nH = pEntry->mnHeight; + else + nH = 2; + nW = 0; // pEntry->mnWidth; + } + else + { + nH = pEntry->mnHeight; + nW = pEntry->mnWidth; + } + + xFont_ = GetDisplay ()->GetFont (pSysFont, nH); + if (pEntry->mnHeight > nMaxFontHeight || pEntry->mnHeight < 2) + aScale_ = Fraction (pEntry->mnHeight, nH); + } + else + { +#ifdef DEBUG + // XXX Fix me: provide a fallback for poor font installations + // we may be reach this if no font matches the GUI font + // MS Sans Serif;Geneva;Helv;WarpSans;Dialog;Lucida; ... */ + fprintf (stderr, "SalGraphicsData::SetFont: Invalid Font Selection\n"); +#endif + } } //-------------------------------------------------------------------------- static sal_Unicode -SwapBytes( const sal_Unicode nIn ) +SwapBytes (const sal_Unicode nIn) { - return ((nIn >> 8) & 0x00ff) | ((nIn << 8) & 0xff00); + return ((nIn >> 8) & 0x00ff) | ((nIn << 8) & 0xff00); } // draw string in a specific multibyte encoding static void -ConvertTextItem16( XTextItem16* pTextItem, - SalConverterCache* pCvt, rtl_TextEncoding nEncoding ) +ConvertTextItem16 (XTextItem16 * pTextItem, + SalConverterCache * pCvt, rtl_TextEncoding nEncoding) { - if ( pTextItem && pTextItem->nchars > 0 ) - { - // convert the string into the font encoding - sal_Size nSize; - sal_Size nBufferSize = pTextItem->nchars * 2; - sal_Char *pBuffer = (sal_Char*)alloca( nBufferSize ); - - nSize = ConvertStringUTF16( (sal_Unicode*)pTextItem->chars, pTextItem->nchars, - pBuffer, nBufferSize, pCvt->GetU2TConverter(nEncoding)); - - sal_Char *pTextChars = (sal_Char*)pTextItem->chars; - int n = 0, m = 0; - - if ( nEncoding == RTL_TEXTENCODING_GB_2312 - || nEncoding == RTL_TEXTENCODING_GBT_12345 - || nEncoding == RTL_TEXTENCODING_GBK - || nEncoding == RTL_TEXTENCODING_BIG5 ) - { - // GB and Big5 needs special treatment since chars can be single or - // double byte: encoding is - // [ 0x00 - 0x7f ] | [ 0x81 - 0xfe ] [ 0x40 - 0x7e 0x80 - 0xfe ] - while ( n < nSize ) - { - if ( (unsigned char)pBuffer[ n ] < 0x80 ) - { - pTextChars[ m++ ] = 0x0; - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - else - { - pTextChars[ m++ ] = pBuffer[ n++ ]; - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - } - pTextItem->nchars = m / 2; - } - else - if ( pCvt->IsSingleByteEncoding(nEncoding) ) - { - // Single Byte encoding has to be padded - while ( n < nSize ) - { - pTextChars[ m++ ] = 0x0; - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - pTextItem->nchars = nSize; - } - else - { - while ( n < nSize ) - { - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - pTextItem->nchars = nSize / 2; - } + if (pTextItem && pTextItem->nchars > 0) + { + // convert the string into the font encoding + sal_Size nSize; + sal_Size nBufferSize = pTextItem->nchars * 2; + sal_Char *pBuffer = (sal_Char *) alloca (nBufferSize); + + nSize = + ConvertStringUTF16 ((sal_Unicode *) pTextItem->chars, + pTextItem->nchars, pBuffer, nBufferSize, + pCvt->GetU2TConverter (nEncoding)); + + sal_Char *pTextChars = (sal_Char *) pTextItem->chars; + int n = 0, m = 0; + + if (nEncoding == RTL_TEXTENCODING_GB_2312 + || nEncoding == RTL_TEXTENCODING_GBT_12345 + || nEncoding == RTL_TEXTENCODING_GBK + || nEncoding == RTL_TEXTENCODING_BIG5) + { + // GB and Big5 needs special treatment since chars can be single or + // double byte: encoding is + // [ 0x00 - 0x7f ] | [ 0x81 - 0xfe ] [ 0x40 - 0x7e 0x80 - 0xfe ] + while (n < nSize) + { + if ((unsigned char) pBuffer[n] & 0x80) + { + switch (nEncoding) + { + case RTL_TEXTENCODING_GB_2312: //The font are store in cjk iso2022 mode do some translation + pTextChars[m++] = pBuffer[n++] & 0x7f; + pTextChars[m++] = pBuffer[n++] & 0x7f; + break; + + default: + pTextChars[m++] = pBuffer[n++]; + pTextChars[m++] = 0x0; + break; + } + } + else + { + pTextChars[m++] = pBuffer[n++]; + pTextChars[m++] = pBuffer[n++]; + } + } + pTextItem->nchars = m / 2; + } + else if (pCvt->IsSingleByteEncoding (nEncoding)) + { + // Single Byte encoding has to be padded + while (n < nSize) + { + pTextChars[m++] = 0x0; + pTextChars[m++] = pBuffer[n++]; + } + pTextItem->nchars = nSize; + } + else + { + while (n < nSize) + { + pTextChars[m++] = pBuffer[n++]; + } + pTextItem->nchars = nSize / 2; } + } } // XXX this is a hack since XPrinter is not multibyte capable // XXX for printing this routine is called for each character void -XPrinterDrawText16( Display* pDisplay, Drawable nDrawable, GC nGC, - int nX, int nY, int nAngle, XTextItem16 *pTextItem16, int nItem ) -{ - // convert XTextItem16 to XTextItem - XTextItem *pTextItem = (XTextItem*)alloca( nItem * sizeof(XTextItem) ); - - for ( int nCurItem = 0; nCurItem < nItem; nCurItem++ ) - { - int nChars = pTextItem16[ nCurItem ].nchars; - char* pDstCharPtr = (char*)alloca( nChars * sizeof(char) ); - XChar2b* pSrcCharPtr = pTextItem16[ nCurItem ].chars; - - pTextItem[ nCurItem ].chars = pDstCharPtr; - pTextItem[ nCurItem ].nchars = nChars; - pTextItem[ nCurItem ].delta = pTextItem16[ nCurItem ].delta; - pTextItem[ nCurItem ].font = pTextItem16[ nCurItem ].font; - - for ( int nCurChar = 0; - nCurChar < nChars; - nCurChar++, pDstCharPtr++, pSrcCharPtr++ ) - { - *pDstCharPtr = (char)pSrcCharPtr->byte2; - } - } - - if ( nAngle != 0 ) - { - for ( int nCurItem = 0; nCurItem < nItem; nCurItem++ ) - { - // XXX FIXME this is broken, because nX and nY is not sufficiently updated - XSetFont( pDisplay, nGC, pTextItem[ nItem ].font ); - if ( XSalCanDrawRotString(pDisplay, nGC) ) - { - XSalDrawRotString( pDisplay, nDrawable, nGC, nX, nY, - pTextItem[ nCurItem ].chars, pTextItem[ nCurItem ].nchars, nAngle ); - } - else - { - XDrawString( pDisplay, nDrawable, nGC, nX, nY, - pTextItem[ nCurItem ].chars, pTextItem[ nCurItem ].nchars ); - } - } - } - else - { - XDrawText( pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem ); - } +XPrinterDrawText16 (Display * pDisplay, Drawable nDrawable, GC nGC, + int nX, int nY, int nAngle, XTextItem16 * pTextItem16, + int nItem) +{ + // convert XTextItem16 to XTextItem + XTextItem *pTextItem = (XTextItem *) alloca (nItem * sizeof (XTextItem)); + + for (int nCurItem = 0; nCurItem < nItem; nCurItem++) + { + int nChars = pTextItem16[nCurItem].nchars; + char *pDstCharPtr = (char *) alloca (nChars * sizeof (char)); + XChar2b *pSrcCharPtr = pTextItem16[nCurItem].chars; + + pTextItem[nCurItem].chars = pDstCharPtr; + pTextItem[nCurItem].nchars = nChars; + pTextItem[nCurItem].delta = pTextItem16[nCurItem].delta; + pTextItem[nCurItem].font = pTextItem16[nCurItem].font; + + for (int nCurChar = 0; + nCurChar < nChars; nCurChar++, pDstCharPtr++, pSrcCharPtr++) + { + *pDstCharPtr = (char) pSrcCharPtr->byte2; + } + } + + if (nAngle != 0) + { + for (int nCurItem = 0; nCurItem < nItem; nCurItem++) + { + // XXX FIXME this is broken, because nX and nY is not sufficiently updated + XSetFont (pDisplay, nGC, pTextItem[nItem].font); + if (XSalCanDrawRotString (pDisplay, nGC)) + { + XSalDrawRotString (pDisplay, nDrawable, nGC, nX, nY, + pTextItem[nCurItem].chars, + pTextItem[nCurItem].nchars, nAngle); + } + else + { + XDrawString (pDisplay, nDrawable, nGC, nX, nY, + pTextItem[nCurItem].chars, + pTextItem[nCurItem].nchars); + } + } + } + else + { + XDrawText (pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem); + } } // draw string vertically static void -DrawVerticalString ( Display *pDisplay, Drawable nDrawable, GC nGC, - int nX, int nY, const sal_Unicode *pStr, int nLength, - ExtendedFontStruct *pFont ) -{ - VerticalTextItem** pTextItems; - int nNumItem = pFont->GetVerticalTextItems( pStr, nLength, RTL_TEXTENCODING_UNICODE, - pStr, pTextItems ); - - for ( int nIdx = 0; nIdx < nNumItem; nIdx++ ) - { - if ( pTextItems[nIdx]->mpXFontStruct == NULL ) - continue; - - XSetFont( pDisplay, nGC, pTextItems[nIdx]->mpXFontStruct->fid ); - for ( int nChar = 0; nChar < pTextItems[nIdx]->mnLength; nChar++ ) - { - XDrawString16( pDisplay, nDrawable, nGC, - nX + pTextItems[nIdx]->mnTransX, - nY + pTextItems[nIdx]->mnTransY, - (XChar2b*)(pTextItems[nIdx]->mpString + nChar), 1 ); - nY += (pTextItems[nIdx]->mbFixed ? - pTextItems[nIdx]->mnFixedAdvance : pTextItems[nIdx]->mpAdvanceAry[nChar]); - } - } - - for (int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++) - { - delete( pTextItems[nIdx2] ); - } - free( pTextItems ); +DrawVerticalString (Display * pDisplay, Drawable nDrawable, GC nGC, + int nX, int nY, const sal_Unicode * pStr, int nLength, + ExtendedFontStruct * pFont) +{ + VerticalTextItem **pTextItems; + int nNumItem = + pFont->GetVerticalTextItems (pStr, nLength, RTL_TEXTENCODING_UNICODE, + pStr, pTextItems); + + for (int nIdx = 0; nIdx < nNumItem; nIdx++) + { + if (pTextItems[nIdx]->mpXFontStruct == NULL) + continue; + + XSetFont (pDisplay, nGC, pTextItems[nIdx]->mpXFontStruct->fid); + for (int nChar = 0; nChar < pTextItems[nIdx]->mnLength; nChar++) + { + XDrawString16 (pDisplay, nDrawable, nGC, + nX + pTextItems[nIdx]->mnTransX, + nY + pTextItems[nIdx]->mnTransY, + (XChar2b *) (pTextItems[nIdx]->mpString + nChar), 1); + nY += (pTextItems[nIdx]->mbFixed ? + pTextItems[nIdx]->mnFixedAdvance : pTextItems[nIdx]-> + mpAdvanceAry[nChar]); + } + } + + for (int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++) + { + delete (pTextItems[nIdx2]); + } + free (pTextItems); } struct VTextItemExt { - rtl_TextEncoding mnEncoding; - const sal_Unicode* mpString; + rtl_TextEncoding mnEncoding; + const sal_Unicode *mpString; }; static void -DrawVerticalTextItem( Display *pDisplay, Drawable nDrawable, GC nGC, - int nX, int nY, XTextItem16* pTextItem, int nItem, - VTextItemExt* pVTextItemExt, ExtendedFontStruct* pFont ) -{ - for ( int nItemIdx = 0; nItemIdx < nItem; nItemIdx++ ) - { - VerticalTextItem** pVTextItems; - int nNumItem = pFont->GetVerticalTextItems( pVTextItemExt[nItemIdx].mpString, - pTextItem[nItemIdx].nchars, - pVTextItemExt[nItemIdx].mnEncoding, - (sal_Unicode *)pTextItem[nItemIdx].chars, - pVTextItems ); - for ( int nIdx = 0; nIdx < nNumItem; nIdx++ ) - { - if ( pVTextItems[nIdx]->mpXFontStruct == NULL ) - continue; - - XSetFont( pDisplay, nGC, pVTextItems[nIdx]->mpXFontStruct->fid ); - for (int nChar = 0; nChar < pVTextItems[nIdx]->mnLength; nChar++ ) - { - XDrawString16( pDisplay, nDrawable, nGC, - nX + pVTextItems[nIdx]->mnTransX, - nY + pVTextItems[nIdx]->mnTransY, - (XChar2b*)(pVTextItems[nIdx]->mpString + nChar), 1 ); - nY += (pVTextItems[nIdx]->mbFixed ? - pVTextItems[nIdx]->mnFixedAdvance : pVTextItems[nIdx]->mpAdvanceAry[nChar]); - } - } - for ( int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++ ) - { - delete( pVTextItems[nIdx2] ); - } - free( pVTextItems ); +DrawVerticalTextItem (Display * pDisplay, Drawable nDrawable, GC nGC, + int nX, int nY, XTextItem16 * pTextItem, int nItem, + VTextItemExt * pVTextItemExt, + ExtendedFontStruct * pFont) +{ + for (int nItemIdx = 0; nItemIdx < nItem; nItemIdx++) + { + VerticalTextItem **pVTextItems; + int nNumItem = + pFont->GetVerticalTextItems (pVTextItemExt[nItemIdx].mpString, + pTextItem[nItemIdx].nchars, + pVTextItemExt[nItemIdx].mnEncoding, + (sal_Unicode *) pTextItem[nItemIdx].chars, + pVTextItems); + for (int nIdx = 0; nIdx < nNumItem; nIdx++) + { + if (pVTextItems[nIdx]->mpXFontStruct == NULL) + continue; + + XSetFont (pDisplay, nGC, pVTextItems[nIdx]->mpXFontStruct->fid); + for (int nChar = 0; nChar < pVTextItems[nIdx]->mnLength; nChar++) + { + XDrawString16 (pDisplay, nDrawable, nGC, + nX + pVTextItems[nIdx]->mnTransX, + nY + pVTextItems[nIdx]->mnTransY, + (XChar2b *) (pVTextItems[nIdx]->mpString + + nChar), 1); + nY += + (pVTextItems[nIdx]->mbFixed ? pVTextItems[nIdx]-> + mnFixedAdvance : pVTextItems[nIdx]->mpAdvanceAry[nChar]); + } } + for (int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++) + { + delete (pVTextItems[nIdx2]); + } + free (pVTextItems); + } } // draw string in one of the fonts / encodings that are available in the // extended font static void -DrawString( Display *pDisplay, Drawable nDrawable, GC nGC, - int nX, int nY, const sal_Unicode *pStr, int nLength, int nAngle, BOOL bVertical, - SalConverterCache *pCvt, ExtendedFontStruct *pFont ) -{ - // sanity check - if ( pFont == NULL || nLength == 0 ) - return; +DrawString (Display * pDisplay, Drawable nDrawable, GC nGC, + int nX, int nY, const sal_Unicode * pStr, int nLength, int nAngle, + BOOL bVertical, SalConverterCache * pCvt, + ExtendedFontStruct * pFont) +{ + // sanity check + if (pFont == NULL || nLength == 0) + return; + + rtl_TextEncoding nAsciiEnc = pFont->GetAsciiEncoding (); + + if (nAsciiEnc == RTL_TEXTENCODING_UNICODE) + { + if (bVertical) + DrawVerticalString (pDisplay, nDrawable, nGC, nX, nY, pStr, nLength, + pFont); + else + { + + // plain Unicode, can handle all chars and can be handled straight forward + XFontStruct *pFontStruct = pFont->GetFontStruct (nAsciiEnc); + + if (pFontStruct == NULL) + return; + + XSetFont (pDisplay, nGC, pFontStruct->fid); + +#ifdef OSL_LITENDIAN + sal_Unicode *pBuffer = + (sal_Unicode *) alloca (nLength * sizeof (sal_Unicode)); + for (int i = 0; i < nLength; i++) + pBuffer[i] = SwapBytes (pStr[i]); +#else + sal_Unicode *pBuffer = const_cast < sal_Unicode * >(pStr); +#endif - rtl_TextEncoding nAsciiEnc = pFont->GetAsciiEncoding(); + XDrawString16 (pDisplay, nDrawable, nGC, nX, nY, + (XChar2b *) pBuffer, nLength); + } + } + else + { + // convert the string to a XTextItem16 with each item chars having the + // encoding matching the font of fontid + XTextItem16 *pTextItem = + (XTextItem16 *) alloca (nLength * sizeof (XTextItem16)); + XChar2b *pMBChar = (XChar2b *) alloca (nLength * sizeof (XChar2b)); + memcpy (pMBChar, pStr, nLength * sizeof (XChar2b)); - if ( nAsciiEnc == RTL_TEXTENCODING_UNICODE ) - { - if ( bVertical ) - DrawVerticalString( pDisplay, nDrawable, nGC, nX, nY, pStr, nLength, pFont ); - else - { + rtl_TextEncoding nEncoding = nAsciiEnc; + XFontStruct *pFontStruct = pFont->GetFontStruct (nEncoding); - // plain Unicode, can handle all chars and can be handled straight forward - XFontStruct* pFontStruct = pFont->GetFontStruct( nAsciiEnc ); + if (pFontStruct == NULL) + return; - if ( pFontStruct == NULL ) - return; - - XSetFont( pDisplay, nGC, pFontStruct->fid ); - - #ifdef OSL_LITENDIAN - sal_Unicode *pBuffer = (sal_Unicode*)alloca( nLength * sizeof(sal_Unicode) ); - for ( int i = 0; i < nLength; i++ ) - pBuffer[ i ] = SwapBytes(pStr[ i ]) ; - #else - sal_Unicode *pBuffer = const_cast(pStr); - #endif + VTextItemExt *pVTextItemExt; + if (bVertical) + pVTextItemExt = + (VTextItemExt *) alloca (nLength * sizeof (VTextItemExt)); - XDrawString16( pDisplay, nDrawable, nGC, nX, nY, (XChar2b*)pBuffer, nLength ); - } - } - else + for (int nChar = 0, nItem = -1; nChar < nLength; nChar++) { - // convert the string to a XTextItem16 with each item chars having the - // encoding matching the font of fontid - XTextItem16 *pTextItem = (XTextItem16*)alloca( nLength * sizeof(XTextItem16) ); - XChar2b *pMBChar = (XChar2b*)alloca( nLength * sizeof(XChar2b) ); - memcpy( pMBChar, pStr, nLength * sizeof(XChar2b) ); - - rtl_TextEncoding nEncoding = nAsciiEnc; - XFontStruct* pFontStruct = pFont->GetFontStruct( nEncoding ); - - if ( pFontStruct == NULL ) - return; + rtl_TextEncoding nOldEnc = nEncoding; + pFont->GetFontStruct (pStr[nChar], &nEncoding, &pFontStruct, pCvt); - VTextItemExt* pVTextItemExt; - if ( bVertical ) - pVTextItemExt = (VTextItemExt*)alloca( nLength * sizeof(VTextItemExt) ); + if (pFontStruct == NULL) + continue; - for ( int nChar = 0, nItem = -1; nChar < nLength; nChar++ ) - { - rtl_TextEncoding nOldEnc = nEncoding; - pFont->GetFontStruct( pStr[nChar], &nEncoding, &pFontStruct, pCvt ); + if ((nItem != -1) && (pFontStruct->fid == pTextItem[nItem].font)) + { + pTextItem[nItem].nchars += 1; + } + else + { + if (nItem != -1) + ConvertTextItem16 (&pTextItem[nItem], pCvt, nOldEnc); - if ( pFontStruct == NULL ) - continue; + ++nItem; - if ( (nItem != -1) && (pFontStruct->fid == pTextItem[ nItem ].font) ) - { - pTextItem[ nItem ].nchars += 1; - } - else - { - if ( nItem != -1 ) - ConvertTextItem16( &pTextItem[ nItem ], pCvt, nOldEnc ); - - ++nItem; - - pTextItem[ nItem ].chars = pMBChar + nChar; - pTextItem[ nItem ].delta = 0; - pTextItem[ nItem ].font = pFontStruct->fid; - pTextItem[ nItem ].nchars = 1; - - if ( bVertical ) - { - pVTextItemExt[ nItem ].mnEncoding = nEncoding; - pVTextItemExt[ nItem ].mpString = pStr + nChar; - } - } - } - ConvertTextItem16( &pTextItem[ nItem ], pCvt, nEncoding ); - ++nItem; + pTextItem[nItem].chars = pMBChar + nChar; + pTextItem[nItem].delta = 0; + pTextItem[nItem].font = pFontStruct->fid; + pTextItem[nItem].nchars = 1; - if ( bVertical ) + if (bVertical) { - pVTextItemExt[ nItem - 1 ].mnEncoding = nEncoding; - DrawVerticalTextItem( pDisplay, nDrawable, nGC, nX, nY, - pTextItem, nItem, pVTextItemExt, pFont ); - free( pVTextItemExt ); + pVTextItemExt[nItem].mnEncoding = nEncoding; + pVTextItemExt[nItem].mpString = pStr + nChar; } - else - { - if ( XSalIsDisplay( pDisplay ) ) - XDrawText16( pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem ); - else - XPrinterDrawText16( pDisplay, nDrawable, nGC, nX, nY, nAngle, - pTextItem, nItem ); - } + } } + ConvertTextItem16 (&pTextItem[nItem], pCvt, nEncoding); + ++nItem; + + if (bVertical) + { + pVTextItemExt[nItem - 1].mnEncoding = nEncoding; + DrawVerticalTextItem (pDisplay, nDrawable, nGC, nX, nY, + pTextItem, nItem, pVTextItemExt, pFont); + free (pVTextItemExt); + } + else + { + if (XSalIsDisplay (pDisplay)) + XDrawText16 (pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem); + else + XPrinterDrawText16 (pDisplay, nDrawable, nGC, nX, nY, nAngle, + pTextItem, nItem); + } + } } //-------------------------------------------------------------------------- -void -SalGraphicsData::DrawText( long nX, long nY, - const sal_Unicode *pStr, USHORT nLen ) +void +SalGraphicsData::DrawText (long nX, long nY, + const sal_Unicode * pStr, USHORT nLen) { #ifndef PRINTER_DUMMY - if( bPrinter_ ) - FaxPhoneComment( GetXDisplay(), pStr, nLen ); + if (bPrinter_) + FaxPhoneComment (GetXDisplay (), pStr, nLen); #endif + +#ifdef __notdef__ + // XXX Fix me this part is not unicode / multibyte aware - #ifdef __notdef__ - // XXX Fix me this part is not unicode / multibyte aware + // Bug: #45670# + // some monospace ISO8859-1 fonts have a hole between chars 128 and 159 + // some applications assume these characters have also the default width + if (!bPrinter_ && PITCH_FIXED == xFont_->GetFont ()->mePitch && nLen > 1) + { + XFontStruct *pXFS = GetFontInfo (); + long nWidth = xFont_->GetDim ()->GetWidth (); - // Bug: #45670# - // some monospace ISO8859-1 fonts have a hole between chars 128 and 159 - // some applications assume these characters have also the default width - if( ! bPrinter_ && - PITCH_FIXED == xFont_->GetFont()->mePitch && - nLen > 1 ) + if (xFont_->GetFixedWidth () != nWidth + || xFont_->GetDefaultWidth () != nWidth) { - XFontStruct *pXFS = GetFontInfo(); - long nWidth = xFont_->GetDim()->GetWidth(); + unsigned int min_char = pXFS->min_char_or_byte2; + unsigned int max_char = pXFS->max_char_or_byte2; + XCharStruct *pXCS = pXFS->per_char - min_char; + + for (USHORT i = 0; i < nLen - 1; i++) + { + unsigned int c = ((unsigned char *) pStr)[i]; + + long nW = c < min_char || c > max_char || !pXFS->per_char + ? xFont_->GetDefaultWidth () : pXCS[c].width; - if( xFont_->GetFixedWidth() != nWidth - || xFont_->GetDefaultWidth() != nWidth ) + if (nW != nWidth) { - unsigned int min_char = pXFS->min_char_or_byte2; - unsigned int max_char = pXFS->max_char_or_byte2; - XCharStruct *pXCS = pXFS->per_char - min_char; - - for( USHORT i = 0; i < nLen-1; i++ ) - { - unsigned int c = ((unsigned char*)pStr)[i]; - - long nW = c < min_char || c > max_char || ! pXFS->per_char - ? xFont_->GetDefaultWidth() - : pXCS[c].width; - - if( nW != nWidth ) - { - long *pDXAry = new long[nLen]; - - for( i = 0; i < nLen; i++ ) - pDXAry[i] = nWidth * (i+1); - - DrawText( nX, nY, pStr, nLen, pDXAry ); - - delete pDXAry; - - return; - } - } + long *pDXAry = new long[nLen]; + + for (i = 0; i < nLen; i++) + pDXAry[i] = nWidth * (i + 1); + + DrawText (nX, nY, pStr, nLen, pDXAry); + + delete pDXAry; + + return; } + } } + } + +#endif /* __notdef__ */ - #endif /* __notdef__ */ - - Display *pDisplay = GetXDisplay(); - SalConverterCache *pCvt = GetDisplay()->GetConverter(); - GC pGC = SelectFont(); - - DrawString( pDisplay, hDrawable_, pGC, nX, nY, - pStr, nLen, nFontOrientation_ * 64 / 10, bFontVertical_, pCvt, xFont_ ); + Display *pDisplay = GetXDisplay (); + SalConverterCache *pCvt = GetDisplay ()->GetConverter (); + GC pGC = SelectFont (); + + DrawString (pDisplay, hDrawable_, pGC, nX, nY, + pStr, nLen, nFontOrientation_ * 64 / 10, bFontVertical_, pCvt, + xFont_); } -void -SalGraphics::DrawText( long nX, long nY, const xub_Unicode* pStr, USHORT nLen ) -{ - maGraphicsData.DrawText( nX, nY, pStr, nLen ); +void +SalGraphics::DrawText (long nX, long nY, const xub_Unicode * pStr, + USHORT nLen) +{ + maGraphicsData.DrawText (nX, nY, pStr, nLen); } //-------------------------------------------------------------------------- -static BOOL -CheckNoNegativeCoordinateWorkaround() +static BOOL +CheckNoNegativeCoordinateWorkaround () { - /* Motivation: one of our clients uses a Solaris 2.4 X86 system with an - XServer for the Matrox Mystique graphics card. This board/server - sometimes does not draw Text with negative x-coordinates into a - virtual device (for unknown reasons). A stock X-server just clips the - part in the negative area. */ - static int nCheck = -2; - if( nCheck == -2 ) - { - char* pCmp = getenv( "SAL_NO_NEGATIVE_TEXT_OFFSET" ); - if( pCmp && ! strncasecmp( pCmp, "true", 4 ) ) - nCheck = 1; - else - nCheck = 0; - } - return nCheck ? TRUE : FALSE; -} - -void -SalGraphicsData::DrawText( - long nX, long nY, - const sal_Unicode* pStr, USHORT nLen, const long* pDXAry ) -{ - #ifndef PRINTER_DUMMY - if( bPrinter_ ) - FaxPhoneComment( GetXDisplay(), pStr, nLen ); - #endif - GC pGC = SelectFont(); - - // workaround for problems with negative coordinates - long* pTmpAry = NULL; - if( nX < 0 && CheckNoNegativeCoordinateWorkaround() ) - { - long nOldX = nX; - while( nX < 0 ) - { - nX = nOldX + *pDXAry; - pStr++, pDXAry++, nLen--; - if( nLen < 1 ) - return; - } - pTmpAry = new long[ nLen ]; - for( int q = 0; q < nLen-1; q++ ) - pTmpAry[q] = pDXAry[q] - ( nX - nOldX ); - pDXAry = pTmpAry; - } - - // draw every single character - SalConverterCache *pCvt = GetDisplay()->GetConverter(); - int angle = nFontOrientation_ * 64 / 10; - BOOL bVertical = bFontVertical_; - Polygon aPolygon(1); - Point aOrigin( nX, nY ); - Point aCharPos; - - DrawString( GetXDisplay(), hDrawable_, pGC, - aOrigin.X(), aOrigin.Y(), pStr, 1, angle, bVertical, pCvt, xFont_ ); + /* Motivation: one of our clients uses a Solaris 2.4 X86 system with an + XServer for the Matrox Mystique graphics card. This board/server + sometimes does not draw Text with negative x-coordinates into a + virtual device (for unknown reasons). A stock X-server just clips the + part in the negative area. */ + static int nCheck = -2; + if (nCheck == -2) + { + char *pCmp = getenv ("SAL_NO_NEGATIVE_TEXT_OFFSET"); + if (pCmp && !strncasecmp (pCmp, "true", 4)) + nCheck = 1; + else + nCheck = 0; + } + return nCheck ? TRUE : FALSE; +} - for( int i = 1; i < nLen ; i++ ) - { - aCharPos = Point( aOrigin.X() + pDXAry[ i - 1 ], aOrigin.Y() ); - aPolygon.SetPoint( aCharPos, 0 ); - aPolygon.Rotate( aOrigin, nFontOrientation_ ); - aCharPos = aPolygon.GetPoint( 0 ); +void +SalGraphicsData::DrawText (long nX, long nY, + const sal_Unicode * pStr, USHORT nLen, + const long *pDXAry) +{ +#ifndef PRINTER_DUMMY + if (bPrinter_) + FaxPhoneComment (GetXDisplay (), pStr, nLen); +#endif + GC pGC = SelectFont (); - DrawString( GetXDisplay(), hDrawable_, pGC, - aCharPos.X(), aCharPos.Y(), pStr + i, 1, angle, bVertical, pCvt, xFont_ ); - } + // workaround for problems with negative coordinates + long *pTmpAry = NULL; + if (nX < 0 && CheckNoNegativeCoordinateWorkaround ()) + { + long nOldX = nX; + while (nX < 0) + { + nX = nOldX + *pDXAry; + pStr++, pDXAry++, nLen--; + if (nLen < 1) + return; + } + pTmpAry = new long[nLen]; + for (int q = 0; q < nLen - 1; q++) + pTmpAry[q] = pDXAry[q] - (nX - nOldX); + pDXAry = pTmpAry; + } + + // draw every single character + SalConverterCache *pCvt = GetDisplay ()->GetConverter (); + int angle = nFontOrientation_ * 64 / 10; + BOOL bVertical = bFontVertical_; + Polygon aPolygon (1); + Point aOrigin (nX, nY); + Point aCharPos; + + DrawString (GetXDisplay (), hDrawable_, pGC, + aOrigin.X (), aOrigin.Y (), pStr, 1, angle, bVertical, pCvt, + xFont_); + + for (int i = 1; i < nLen; i++) + { + aCharPos = Point (aOrigin.X () + pDXAry[i - 1], aOrigin.Y ()); + aPolygon.SetPoint (aCharPos, 0); + aPolygon.Rotate (aOrigin, nFontOrientation_); + aCharPos = aPolygon.GetPoint (0); + + DrawString (GetXDisplay (), hDrawable_, pGC, + aCharPos.X (), aCharPos.Y (), pStr + i, 1, angle, bVertical, + pCvt, xFont_); + } - if( pTmpAry ) - delete pTmpAry; + if (pTmpAry) + delete pTmpAry; } // ---------------------------------------------------------------------------- @@ -973,212 +1006,220 @@ // // ---------------------------------------------------------------------------- -USHORT -SalGraphics::SetFont( ImplFontSelectData *pEntry ) -{ - maGraphicsData.SetFont( pEntry ); - return _IsPrinter() ? SAL_SETFONT_USEDRAWTEXTARRAY : 0; +USHORT SalGraphics::SetFont (ImplFontSelectData * pEntry) +{ + maGraphicsData.SetFont (pEntry); + return _IsPrinter ()? SAL_SETFONT_USEDRAWTEXTARRAY : 0; } // ---------------------------------------------------------------------------- -void -SalGraphics::DrawTextArray( long nX, long nY, - const xub_Unicode *pStr, USHORT nLen, const long *pDXAry ) -{ - maGraphicsData.DrawText( nX, nY, pStr, nLen, pDXAry ); +void +SalGraphics::DrawTextArray (long nX, long nY, + const xub_Unicode * pStr, USHORT nLen, + const long *pDXAry) +{ + maGraphicsData.DrawText (nX, nY, pStr, nLen, pDXAry); } // ---------------------------------------------------------------------------- -void -SalGraphics::SetTextColor( SalColor nSalColor ) +void +SalGraphics::SetTextColor (SalColor nSalColor) { - if( _GetTextColor() != nSalColor ) - { - _GetTextColor() = nSalColor; - _GetTextPixel() = _GetPixel( nSalColor ); - _IsFontGC() = FALSE; - } + if (_GetTextColor () != nSalColor) + { + _GetTextColor () = nSalColor; + _GetTextPixel () = _GetPixel (nSalColor); + _IsFontGC () = FALSE; + } } // ---------------------------------------------------------------------------- -void -SalGraphics::GetDevFontList( ImplDevFontList *pList ) +void +SalGraphics::GetDevFontList (ImplDevFontList * pList) { - XlfdStorage* pFonts = _GetDisplay()->GetXlfdList(); + XlfdStorage *pFonts = _GetDisplay ()->GetXlfdList (); - for ( int nIdx = 0; nIdx < pFonts->GetCount(); nIdx++ ) - { - ImplFontData *pFontData = new ImplFontData; - pFonts->Get(nIdx)->ToImplFontData( pFontData ); - pList->Add( pFontData ); - } + for (int nIdx = 0; nIdx < pFonts->GetCount (); nIdx++) + { + ImplFontData *pFontData = new ImplFontData; + pFonts->Get (nIdx)->ToImplFontData (pFontData); + pList->Add (pFontData); + } } // ---------------------------------------------------------------------------- -inline long -sal_DivideNeg( long n1, long n2 ) +inline long +sal_DivideNeg (long n1, long n2) { - return ( n1 < 0 ) ? (n1 - n2 / 2) / n2 : (n1 + n2 / 2) / n2; + return (n1 < 0) ? (n1 - n2 / 2) / n2 : (n1 + n2 / 2) / n2; } -void -SalGraphics::GetFontMetric( ImplFontMetricData *pMetric ) +void +SalGraphics::GetFontMetric (ImplFontMetricData * pMetric) { - ExtendedFontStruct* pFont = maGraphicsData.xFont_; + ExtendedFontStruct *pFont = maGraphicsData.xFont_; - if ( pFont != NULL ) - { - pFont->ToImplFontMetricData( pMetric ); + if (pFont != NULL) + { + pFont->ToImplFontMetricData (pMetric); - if( XSalCanDrawRotString( maGraphicsData.GetXDisplay(), None ) ) - pMetric->mnOrientation = maGraphicsData.nFontOrientation_; - if ( maGraphicsData.bFontVertical_ ) - pMetric->mnOrientation = 2700; + if (XSalCanDrawRotString (maGraphicsData.GetXDisplay (), None)) + pMetric->mnOrientation = maGraphicsData.nFontOrientation_; + if (maGraphicsData.bFontVertical_) + pMetric->mnOrientation = 2700; - long n; + long n; - n = maGraphicsData.aScale_.GetNumerator(); - if( n != 1 ) - { - pMetric->mnWidth *= n; - pMetric->mnAscent *= n; - pMetric->mnDescent *= n; - pMetric->mnLeading *= n; - pMetric->mnSlant *= n; - } - - n = maGraphicsData.aScale_.GetDenominator(); - if( n != 1 ) - { - pMetric->mnWidth = Divide( pMetric->mnWidth, n ); - pMetric->mnAscent = sal_DivideNeg( pMetric->mnAscent, n ); - pMetric->mnDescent = sal_DivideNeg( pMetric->mnDescent, n ); - pMetric->mnLeading = sal_DivideNeg( pMetric->mnLeading, n ); - pMetric->mnSlant = sal_DivideNeg( pMetric->mnSlant, n ); - } + n = maGraphicsData.aScale_.GetNumerator (); + if (n != 1) + { + pMetric->mnWidth *= n; + pMetric->mnAscent *= n; + pMetric->mnDescent *= n; + pMetric->mnLeading *= n; + pMetric->mnSlant *= n; } + + n = maGraphicsData.aScale_.GetDenominator (); + if (n != 1) + { + pMetric->mnWidth = Divide (pMetric->mnWidth, n); + pMetric->mnAscent = sal_DivideNeg (pMetric->mnAscent, n); + pMetric->mnDescent = sal_DivideNeg (pMetric->mnDescent, n); + pMetric->mnLeading = sal_DivideNeg (pMetric->mnLeading, n); + pMetric->mnSlant = sal_DivideNeg (pMetric->mnSlant, n); + } + } } // --------------------------------------------------------------------------- static long -InitializeWidthArray( long *pWidthArray, sal_Size nItems, int nValue = 0 ) +InitializeWidthArray (long *pWidthArray, sal_Size nItems, int nValue = 0) { - const long nPrecision = 1; - - for ( int i = 0; i < nItems; i++, pWidthArray++ ) - *pWidthArray = nValue; - - return nPrecision; -} - -long -SalGraphics::GetCharWidth( USHORT nChar1, USHORT nChar2, long *pWidthAry ) -{ - // return the precision of the calculated charwidth, e.g. 1000 = 3 digits - // defaultet to 1 for now - const long nPrecision = 1; - int nRequestedWidth = nChar2 - nChar1 + 1; - int nCharWidth; - - // XXX sanity check, this may happen if no font at all is installed - // or no system font matches the requirements for the user interface - if ( maGraphicsData.xFont_ == NULL ) - return InitializeWidthArray( pWidthAry, nRequestedWidth, 12 ); - - // the font should know it's metrics best - SalDisplay *pSalDisplay = maGraphicsData.GetDisplay(); - - nCharWidth = maGraphicsData.xFont_->GetCharWidth( - pSalDisplay->GetConverter(), nChar1, nChar2, pWidthAry ); - - // XXX sanity check, this may happen if the font cannot be loaded/queried - // either because of a garbled fontpath or because of invalid fontfile - if ( nCharWidth != nRequestedWidth ) - InitializeWidthArray( pWidthAry + nCharWidth, - nRequestedWidth - nCharWidth ); - - // handle internal scaling - const long nNumerator = maGraphicsData.aScale_.GetNumerator(); - const long nDenominator = maGraphicsData.aScale_.GetDenominator(); - long *pPtr; - sal_Unicode nChar; - - if ( nNumerator != 1 ) - for( pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) - *pPtr *= nNumerator; - if ( nDenominator != 1 ) - for( pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) - *pPtr = Divide( *pPtr, nDenominator ); + const long nPrecision = 1; + + for (int i = 0; i < nItems; i++, pWidthArray++) + *pWidthArray = nValue; + + return nPrecision; +} + +long +SalGraphics::GetCharWidth (USHORT nChar1, USHORT nChar2, long *pWidthAry) +{ + // return the precision of the calculated charwidth, e.g. 1000 = 3 digits + // defaultet to 1 for now + const long nPrecision = 1; + int nRequestedWidth = nChar2 - nChar1 + 1; + int nCharWidth; + + // XXX sanity check, this may happen if no font at all is installed + // or no system font matches the requirements for the user interface + if (maGraphicsData.xFont_ == NULL) + return InitializeWidthArray (pWidthAry, nRequestedWidth, 12); + + // the font should know it's metrics best + SalDisplay *pSalDisplay = maGraphicsData.GetDisplay (); + + nCharWidth = + maGraphicsData.xFont_->GetCharWidth (pSalDisplay->GetConverter (), nChar1, + nChar2, pWidthAry); + + // XXX sanity check, this may happen if the font cannot be loaded/queried + // either because of a garbled fontpath or because of invalid fontfile + if (nCharWidth != nRequestedWidth) + InitializeWidthArray (pWidthAry + nCharWidth, + nRequestedWidth - nCharWidth); + + // handle internal scaling + const long nNumerator = maGraphicsData.aScale_.GetNumerator (); + const long nDenominator = maGraphicsData.aScale_.GetDenominator (); + long *pPtr; + sal_Unicode nChar; + + if (nNumerator != 1) + for (pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) + *pPtr *= nNumerator; + if (nDenominator != 1) + for (pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) + *pPtr = Divide (*pPtr, nDenominator); - // return - return nPrecision; + // return + return nPrecision; } // --------------------------------------------------------------------------- -extern unsigned char TranslateCharName( char* ); +extern unsigned char TranslateCharName (char *); -ULONG -SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData *pKernPairs ) +ULONG SalGraphics::GetKernPairs (ULONG nPairs, ImplKernPairData * pKernPairs) { - if( ! _IsPrinter() ) - return 0; + if (!_IsPrinter ()) + return 0; - // get pair kerning table ( internal data from xprinter ) - int i, nCurPair=0; - - // XXX Fix me, improve this to be multi encoding aware: merge kern - // pair list for all encodings available in the xfont - rtl_TextEncoding nEncoding = maGraphicsData.xFont_->GetAsciiEncoding(); - XFontStruct *pXFS = maGraphicsData.xFont_->GetFontStruct( nEncoding ); - XExtData *pXES = pXFS->ext_data; - - for( i = 0; pXES && i < 2; i++, pXES = pXES->next ); - if( i < 2 ) - return 0; - XpPairKernData* pXpPKD = (XpPairKernData*)(pXES->private_data); - PairKernData* pPKD = pXpPKD->pkd; - - for( i = 0, nCurPair=0; i < pXpPKD->numOfPairs; i++ ) - { - unsigned char c1 = TranslateCharName( pPKD[i].name1 ); - unsigned char c2 = TranslateCharName( pPKD[i].name2 ); - if( c1 && c2 ) - { - if( pKernPairs && nCurPair < nPairs ) - { - pKernPairs[ nCurPair ].mnChar1 = c1; - pKernPairs[ nCurPair ].mnChar2 = c2; - pKernPairs[ nCurPair ].mnKern = - (long)(pPKD[i].xamt * pXpPKD->pointsize / 1000 ); - } - nCurPair++; - } + // get pair kerning table ( internal data from xprinter ) + int + i, nCurPair = 0; + + // XXX Fix me, improve this to be multi encoding aware: merge kern + // pair list for all encodings available in the xfont + rtl_TextEncoding + nEncoding = maGraphicsData.xFont_->GetAsciiEncoding (); + XFontStruct * + pXFS = maGraphicsData.xFont_->GetFontStruct (nEncoding); + XExtData * + pXES = pXFS->ext_data; + + for (i = 0; pXES && i < 2; i++, pXES = pXES->next); + if (i < 2) + return 0; + XpPairKernData * + pXpPKD = (XpPairKernData *) (pXES->private_data); + PairKernData * + pPKD = pXpPKD->pkd; + + for (i = 0, nCurPair = 0; i < pXpPKD->numOfPairs; i++) + { + unsigned char + c1 = TranslateCharName (pPKD[i].name1); + unsigned char + c2 = TranslateCharName (pPKD[i].name2); + if (c1 && c2) + { + if (pKernPairs && nCurPair < nPairs) + { + pKernPairs[nCurPair].mnChar1 = c1; + pKernPairs[nCurPair].mnChar2 = c2; + pKernPairs[nCurPair].mnKern = + (long) (pPKD[i].xamt * pXpPKD->pointsize / 1000); + } + nCurPair++; } + } - return nCurPair; + return nCurPair; } // --------------------------------------------------------------------------- -BOOL -SalGraphics::GetGlyphBoundRect( xub_Unicode c, - long *pX, long *pY, long *pDX, long *pDY ) +BOOL + SalGraphics::GetGlyphBoundRect (xub_Unicode c, + long *pX, long *pY, long *pDX, long *pDY) { - return FALSE; + return FALSE; } // --------------------------------------------------------------------------- -ULONG -SalGraphics::GetGlyphOutline( xub_Unicode c, - USHORT **ppPolySizes, SalPoint **ppPoints, BYTE **ppFlags ) +ULONG + SalGraphics::GetGlyphOutline (xub_Unicode c, + USHORT ** ppPolySizes, SalPoint ** ppPoints, + BYTE ** ppFlags) { - return 0; + return 0; } -