Lines 125-174
Link Here
|
125 |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
125 |
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
126 |
|
126 |
|
127 |
#ifndef PRINTER_DUMMY |
127 |
#ifndef PRINTER_DUMMY |
128 |
static void |
128 |
static void |
129 |
FaxPhoneComment( Display* pDisplay, const sal_Unicode* pStr, USHORT nLen ) |
129 |
FaxPhoneComment (Display * pDisplay, const sal_Unicode * pStr, USHORT nLen) |
130 |
{ |
130 |
{ |
131 |
#define FAX_PHONE_TOKEN "@@#" |
131 |
#define FAX_PHONE_TOKEN "@@#" |
132 |
#define FAX_PHONE_TOKEN_LENGTH 3 |
132 |
#define FAX_PHONE_TOKEN_LENGTH 3 |
133 |
#define FAX_END_TOKEN "@@" |
133 |
#define FAX_END_TOKEN "@@" |
134 |
|
134 |
|
135 |
USHORT nPos; |
135 |
USHORT nPos; |
136 |
ByteString aPhone( pStr, nLen, gsl_getSystemTextEncoding() ); |
136 |
ByteString aPhone (pStr, nLen, gsl_getSystemTextEncoding ()); |
137 |
|
137 |
|
138 |
static ByteString aPhoneNumber; |
138 |
static ByteString aPhoneNumber; |
139 |
static BOOL bIsCollecting = FALSE; |
139 |
static BOOL bIsCollecting = FALSE; |
140 |
|
140 |
|
141 |
if( ! bIsCollecting ) |
141 |
if (!bIsCollecting) |
142 |
{ |
142 |
{ |
143 |
if( ( nPos = aPhone.Search( FAX_PHONE_TOKEN ) ) != STRING_NOTFOUND ) |
143 |
if ((nPos = aPhone.Search (FAX_PHONE_TOKEN)) != STRING_NOTFOUND) |
144 |
{ |
144 |
{ |
145 |
aPhone.Erase( 0, nPos + FAX_PHONE_TOKEN_LENGTH ); |
145 |
aPhone.Erase (0, nPos + FAX_PHONE_TOKEN_LENGTH); |
146 |
bIsCollecting = TRUE; |
146 |
bIsCollecting = TRUE; |
147 |
aPhoneNumber.Erase(); |
147 |
aPhoneNumber.Erase (); |
148 |
} |
148 |
} |
149 |
} |
149 |
} |
150 |
if( bIsCollecting ) |
150 |
if (bIsCollecting) |
151 |
{ |
151 |
{ |
152 |
if( ( nPos = aPhone.Search( FAX_END_TOKEN ) ) != STRING_NOTFOUND ) |
152 |
if ((nPos = aPhone.Search (FAX_END_TOKEN)) != STRING_NOTFOUND) |
153 |
{ |
153 |
{ |
154 |
aPhone.Erase( nPos ); |
154 |
aPhone.Erase (nPos); |
155 |
bIsCollecting = FALSE; |
155 |
bIsCollecting = FALSE; |
156 |
} |
156 |
} |
157 |
aPhoneNumber += aPhone; |
157 |
aPhoneNumber += aPhone; |
158 |
if( ! bIsCollecting ) |
158 |
if (!bIsCollecting) |
159 |
{ |
159 |
{ |
160 |
aPhone = "PhoneNumber("; |
160 |
aPhone = "PhoneNumber("; |
161 |
aPhone += aPhoneNumber; |
161 |
aPhone += aPhoneNumber; |
162 |
aPhone += ")\n"; |
162 |
aPhone += ")\n"; |
163 |
XpPSComment( pDisplay, aPhone.GetBuffer() ); |
163 |
XpPSComment (pDisplay, aPhone.GetBuffer ()); |
164 |
aPhoneNumber = ByteString(); |
164 |
aPhoneNumber = ByteString (); |
165 |
} |
165 |
} |
166 |
} |
166 |
} |
167 |
if( aPhoneNumber.Len() > 1024 ) |
167 |
if (aPhoneNumber.Len () > 1024) |
168 |
{ |
168 |
{ |
169 |
bIsCollecting = FALSE; |
169 |
bIsCollecting = FALSE; |
170 |
aPhoneNumber = ByteString(); |
170 |
aPhoneNumber = ByteString (); |
171 |
} |
171 |
} |
172 |
} |
172 |
} |
173 |
#endif |
173 |
#endif |
174 |
|
174 |
|
Lines 178-406
Link Here
|
178 |
// |
178 |
// |
179 |
// ---------------------------------------------------------------------------- |
179 |
// ---------------------------------------------------------------------------- |
180 |
|
180 |
|
181 |
XlfdStorage* |
181 |
XlfdStorage * |
182 |
SalDisplay::GetXlfdList() |
182 |
SalDisplay::GetXlfdList () |
183 |
{ |
183 |
{ |
184 |
if ( mpFontList != NULL ) |
184 |
if (mpFontList != NULL) |
185 |
{ |
185 |
{ |
186 |
return mpFontList; |
186 |
return mpFontList; |
187 |
} |
187 |
} |
188 |
else |
188 |
else |
189 |
{ |
189 |
{ |
190 |
// on a display an xlfd of *-0-0-75-75-* means this is a scalable |
190 |
// on a display an xlfd of *-0-0-75-75-* means this is a scalable |
191 |
// bitmap font, thus it is ugly and thus to avoid. On a printer |
191 |
// bitmap font, thus it is ugly and thus to avoid. On a printer |
192 |
// *-0-0-300-300-* means this is a printer resident font thus nice |
192 |
// *-0-0-300-300-* means this is a printer resident font thus nice |
193 |
// thus to prefer :-( |
193 |
// thus to prefer :-( |
194 |
eDeviceT eDevice = this->IsDisplay() ? eDeviceDisplay : eDevicePrinter; |
194 |
eDeviceT eDevice = this->IsDisplay ()? eDeviceDisplay : eDevicePrinter; |
195 |
|
195 |
|
196 |
mpFactory = new AttributeProvider( eDevice ); |
196 |
mpFactory = new AttributeProvider (eDevice); |
197 |
mpFontList = new XlfdStorage(); |
197 |
mpFontList = new XlfdStorage (); |
198 |
|
198 |
|
199 |
int i, nFontCount; |
199 |
int i, nFontCount; |
200 |
const int nMaxCount = 64 * 1024 - 1; |
200 |
const int nMaxCount = 64 * 1024 - 1; |
201 |
Display *pDisplay = GetDisplay(); |
201 |
Display *pDisplay = GetDisplay (); |
202 |
char **ppFontList = XListFonts(pDisplay, "-*", nMaxCount, &nFontCount); |
202 |
char **ppFontList = XListFonts (pDisplay, "-*", nMaxCount, &nFontCount); |
203 |
|
203 |
|
204 |
// |
204 |
// |
205 |
// create a list of simple Xlfd font information |
205 |
// create a list of simple Xlfd font information |
206 |
// |
206 |
// |
|
|
207 |
|
208 |
Xlfd *pXlfdList = (Xlfd *) malloc (nFontCount * sizeof (Xlfd)); |
209 |
int nXlfdCount = 0; |
210 |
|
211 |
for (i = 0; i < nFontCount; i++) |
212 |
{ |
213 |
if (pXlfdList[nXlfdCount].FromString (ppFontList[i], mpFactory)) |
214 |
++nXlfdCount; |
215 |
} |
216 |
|
217 |
XFreeFontNames (ppFontList); |
218 |
|
219 |
// classification information is needed for sorting, classification |
220 |
// of charset (i.e. iso8859-1 <-> ansi-1252) depends on wether the |
221 |
// display points to a printer or to a real display. On a printer all |
222 |
// iso8859-1 fonts are really capable of ansi-1252 |
223 |
mpFactory->AddClassification (); |
224 |
// add some pretty print description |
225 |
mpFactory->AddAnnotation (); |
226 |
// misc feature checking |
227 |
mpFactory->TagFeature (); |
228 |
|
229 |
// sort according to font style |
230 |
qsort (pXlfdList, nXlfdCount, sizeof (Xlfd), XlfdCompare); |
231 |
|
232 |
// |
233 |
// create a font list with merged encoding information |
234 |
// |
235 |
|
236 |
BitmapXlfdStorage aBitmapList; |
237 |
ScalableXlfd *pScalableFont = NULL; |
238 |
PrinterFontXlfd *pPrinterFont = NULL; |
239 |
|
240 |
int nFrom = 0; |
241 |
for (i = 0; i < nXlfdCount; i++) |
242 |
{ |
243 |
// exclude openlook glyph and cursor |
244 |
Attribute *pAttr = |
245 |
mpFactory->RetrieveFamily (pXlfdList[i].mnFamily); |
246 |
if (pAttr-> |
247 |
HasFeature (XLFD_FEATURE_OL_GLYPH | XLFD_FEATURE_OL_CURSOR)) |
248 |
{ |
249 |
continue; |
250 |
} |
251 |
// exclude fonts with unknown encoding |
252 |
if (pXlfdList[i].GetEncoding () == RTL_TEXTENCODING_DONTKNOW) |
253 |
{ |
254 |
continue; |
255 |
} |
256 |
|
257 |
Bool bSameOutline = |
258 |
pXlfdList[i].SameFontoutline (pXlfdList + nFrom); |
259 |
XlfdFonttype eType = pXlfdList[i].Fonttype (); |
260 |
|
261 |
// flush the old merged font list if the name doesn't match any more |
262 |
if (!bSameOutline) |
263 |
{ |
264 |
mpFontList->Add (pScalableFont); |
265 |
pScalableFont = NULL; |
266 |
mpFontList->Add (pPrinterFont); |
267 |
pPrinterFont = NULL; |
268 |
mpFontList->Add (&aBitmapList); |
269 |
aBitmapList.Reset (); |
270 |
} |
271 |
|
272 |
// merge the font or generate a new one |
273 |
switch (eType) |
274 |
{ |
275 |
case eTypeScalable: |
276 |
|
277 |
if (pScalableFont == NULL) |
278 |
pScalableFont = new ScalableXlfd; |
279 |
pScalableFont->AddEncoding (pXlfdList + i); |
280 |
|
281 |
break; |
282 |
|
283 |
case eTypeBitmap: |
284 |
|
285 |
aBitmapList.AddBitmapFont (pXlfdList + i); |
286 |
|
287 |
break; |
288 |
|
289 |
case eTypePrinterBuiltIn: |
290 |
case eTypePrinterDownload: |
291 |
|
292 |
if (pPrinterFont == NULL) |
293 |
pPrinterFont = new PrinterFontXlfd; |
294 |
pPrinterFont->AddEncoding (pXlfdList + i); |
295 |
|
296 |
break; |
297 |
|
298 |
case eTypeScalableBitmap: |
299 |
default: |
300 |
|
301 |
break; |
302 |
} |
303 |
|
304 |
nFrom = i; |
305 |
} |
306 |
|
307 |
// flush the merged list into the global list |
308 |
mpFontList->Add (pScalableFont); |
309 |
mpFontList->Add (pPrinterFont); |
310 |
mpFontList->Add (&aBitmapList); |
311 |
|
312 |
// cleanup the list of simple font information |
313 |
if (pXlfdList != NULL) |
314 |
free (pXlfdList); |
207 |
|
315 |
|
208 |
Xlfd *pXlfdList = (Xlfd*)malloc( nFontCount * sizeof(Xlfd) ); |
316 |
return mpFontList; |
209 |
int nXlfdCount = 0; |
317 |
} |
210 |
|
|
|
211 |
for ( i = 0; i < nFontCount; i++ ) |
212 |
{ |
213 |
if ( pXlfdList[ nXlfdCount ].FromString(ppFontList[i], mpFactory) ) |
214 |
++nXlfdCount; |
215 |
} |
216 |
|
217 |
XFreeFontNames( ppFontList ); |
218 |
|
219 |
// classification information is needed for sorting, classification |
220 |
// of charset (i.e. iso8859-1 <-> ansi-1252) depends on wether the |
221 |
// display points to a printer or to a real display. On a printer all |
222 |
// iso8859-1 fonts are really capable of ansi-1252 |
223 |
mpFactory->AddClassification(); |
224 |
// add some pretty print description |
225 |
mpFactory->AddAnnotation(); |
226 |
// misc feature checking |
227 |
mpFactory->TagFeature(); |
228 |
|
229 |
// sort according to font style |
230 |
qsort( pXlfdList, nXlfdCount, sizeof(Xlfd), XlfdCompare ); |
231 |
|
232 |
// |
233 |
// create a font list with merged encoding information |
234 |
// |
235 |
|
236 |
BitmapXlfdStorage aBitmapList; |
237 |
ScalableXlfd *pScalableFont = NULL; |
238 |
PrinterFontXlfd *pPrinterFont = NULL; |
239 |
|
240 |
int nFrom = 0; |
241 |
for ( i = 0; i < nXlfdCount; i++ ) |
242 |
{ |
243 |
// exclude openlook glyph and cursor |
244 |
Attribute *pAttr = mpFactory->RetrieveFamily(pXlfdList[i].mnFamily); |
245 |
if ( pAttr->HasFeature( XLFD_FEATURE_OL_GLYPH |
246 |
| XLFD_FEATURE_OL_CURSOR) ) |
247 |
{ |
248 |
continue; |
249 |
} |
250 |
// exclude fonts with unknown encoding |
251 |
if ( pXlfdList[i].GetEncoding() == RTL_TEXTENCODING_DONTKNOW ) |
252 |
{ |
253 |
continue; |
254 |
} |
255 |
|
256 |
Bool bSameOutline = pXlfdList[i].SameFontoutline(pXlfdList + nFrom); |
257 |
XlfdFonttype eType = pXlfdList[i].Fonttype(); |
258 |
|
259 |
// flush the old merged font list if the name doesn't match any more |
260 |
if ( !bSameOutline ) |
261 |
{ |
262 |
mpFontList->Add( pScalableFont ); pScalableFont = NULL; |
263 |
mpFontList->Add( pPrinterFont ); pPrinterFont = NULL; |
264 |
mpFontList->Add( &aBitmapList ); aBitmapList.Reset(); |
265 |
} |
266 |
|
267 |
// merge the font or generate a new one |
268 |
switch( eType ) |
269 |
{ |
270 |
case eTypeScalable: |
271 |
|
272 |
if ( pScalableFont == NULL ) |
273 |
pScalableFont = new ScalableXlfd; |
274 |
pScalableFont->AddEncoding(pXlfdList + i); |
275 |
|
276 |
break; |
277 |
|
278 |
case eTypeBitmap: |
279 |
|
280 |
aBitmapList.AddBitmapFont( pXlfdList + i ); |
281 |
|
282 |
break; |
283 |
|
284 |
case eTypePrinterBuiltIn: |
285 |
case eTypePrinterDownload: |
286 |
|
287 |
if ( pPrinterFont == NULL ) |
288 |
pPrinterFont = new PrinterFontXlfd; |
289 |
pPrinterFont->AddEncoding( pXlfdList + i ); |
290 |
|
291 |
break; |
292 |
|
293 |
case eTypeScalableBitmap: |
294 |
default: |
295 |
|
296 |
break; |
297 |
} |
298 |
|
299 |
nFrom = i; |
300 |
} |
301 |
|
302 |
// flush the merged list into the global list |
303 |
mpFontList->Add( pScalableFont ); |
304 |
mpFontList->Add( pPrinterFont ); |
305 |
mpFontList->Add( &aBitmapList ); |
306 |
|
307 |
// cleanup the list of simple font information |
308 |
if ( pXlfdList != NULL ) |
309 |
free( pXlfdList ); |
310 |
|
311 |
return mpFontList; |
312 |
} |
313 |
} |
318 |
} |
314 |
|
319 |
|
315 |
// --------------------------------------------------------------------------- |
320 |
// --------------------------------------------------------------------------- |
316 |
|
321 |
|
317 |
ExtendedFontStruct* |
322 |
ExtendedFontStruct * |
318 |
SalDisplay::GetFont( ExtendedXlfd *pRequestedFont, int nPixelSize ) |
323 |
SalDisplay::GetFont (ExtendedXlfd * pRequestedFont, int nPixelSize) |
319 |
{ |
324 |
{ |
320 |
if( !pFontCache_ ) |
325 |
if (!pFontCache_) |
321 |
{ |
326 |
{ |
322 |
mpCvtCache = new SalConverterCache; |
327 |
mpCvtCache = new SalConverterCache; |
323 |
pFontCache_ = new SalFontCache( 64, 64, 16 ); // ??? |
328 |
pFontCache_ = new SalFontCache (64, 64, 16); // ??? |
324 |
} |
329 |
} |
325 |
else |
330 |
else |
326 |
{ |
331 |
{ |
327 |
ExtendedFontStruct *pItem; |
332 |
ExtendedFontStruct *pItem; |
328 |
for ( pItem = pFontCache_->First(); |
333 |
for (pItem = pFontCache_->First (); |
329 |
pItem != NULL; |
334 |
pItem != NULL; pItem = pFontCache_->Next ()) |
330 |
pItem = pFontCache_->Next() ) |
335 |
{ |
331 |
{ |
336 |
if (pItem->Match (pRequestedFont, nPixelSize)) |
332 |
if ( pItem->Match(pRequestedFont, nPixelSize) ) |
337 |
{ |
333 |
{ |
338 |
if (pFontCache_->GetCurPos ()) |
334 |
if( pFontCache_->GetCurPos() ) |
339 |
{ |
335 |
{ |
340 |
pFontCache_->Remove (pItem); |
336 |
pFontCache_->Remove( pItem ); |
341 |
pFontCache_->Insert (pItem, 0UL); |
337 |
pFontCache_->Insert( pItem, 0UL ); |
342 |
} |
338 |
} |
343 |
return pItem; |
339 |
return pItem; |
344 |
} |
340 |
} |
345 |
} |
341 |
} |
346 |
} |
342 |
} |
347 |
|
343 |
|
348 |
// before we expand the cache, we look for very old and unused items |
344 |
// before we expand the cache, we look for very old and unused items |
349 |
if (pFontCache_->Count () >= 64) |
345 |
if( pFontCache_->Count() >= 64 ) |
350 |
{ |
346 |
{ |
351 |
ExtendedFontStruct *pItem; |
347 |
ExtendedFontStruct *pItem; |
352 |
for (pItem = pFontCache_->Last (); |
348 |
for ( pItem = pFontCache_->Last(); |
353 |
pItem != NULL; pItem = pFontCache_->Prev ()) |
349 |
pItem != NULL; |
354 |
{ |
350 |
pItem = pFontCache_->Prev() ) |
355 |
if (1 == pItem->GetRefCount ()) |
351 |
{ |
356 |
{ |
352 |
if( 1 == pItem->GetRefCount() ) |
357 |
pFontCache_->Remove (pItem); |
353 |
{ |
358 |
pItem->ReleaseRef (); |
354 |
pFontCache_->Remove( pItem ); |
359 |
|
355 |
pItem->ReleaseRef(); |
360 |
if (pFontCache_->Count () < 64) |
356 |
|
361 |
break; |
357 |
if( pFontCache_->Count() < 64 ) |
362 |
} |
358 |
break; |
363 |
} |
359 |
} |
364 |
} |
360 |
} |
365 |
|
361 |
} |
366 |
ExtendedFontStruct *pItem = new ExtendedFontStruct (GetDisplay (), |
362 |
|
367 |
nPixelSize, |
363 |
ExtendedFontStruct *pItem = new ExtendedFontStruct( GetDisplay(), |
368 |
pRequestedFont, |
364 |
nPixelSize, pRequestedFont, mpCvtCache ); |
369 |
mpCvtCache); |
365 |
pFontCache_->Insert( pItem, 0UL ); |
370 |
pFontCache_->Insert (pItem, 0UL); |
366 |
pItem->AddRef(); |
371 |
pItem->AddRef (); |
367 |
|
372 |
|
368 |
return pItem; |
373 |
return pItem; |
369 |
} |
374 |
} |
370 |
|
375 |
|
371 |
// --------------------------------------------------------------------------- |
376 |
// --------------------------------------------------------------------------- |
372 |
|
377 |
|
373 |
void |
378 |
void |
374 |
SalDisplay::DestroyFontCache() |
379 |
SalDisplay::DestroyFontCache () |
375 |
{ |
380 |
{ |
376 |
if( pFontCache_ ) |
381 |
if (pFontCache_) |
377 |
{ |
382 |
{ |
378 |
ExtendedFontStruct *pItem = pFontCache_->First(); |
383 |
ExtendedFontStruct *pItem = pFontCache_->First (); |
379 |
while( pItem ) |
384 |
while (pItem) |
380 |
{ |
385 |
{ |
381 |
delete pItem; |
386 |
delete pItem; |
382 |
pItem = pFontCache_->Next(); |
387 |
pItem = pFontCache_->Next (); |
383 |
} |
388 |
} |
384 |
delete pFontCache_; |
389 |
delete pFontCache_; |
385 |
} |
390 |
} |
386 |
if( mpFontList ) |
391 |
if (mpFontList) |
387 |
{ |
392 |
{ |
388 |
mpFontList->Dispose(); |
393 |
mpFontList->Dispose (); |
389 |
delete mpFontList; |
394 |
delete mpFontList; |
390 |
} |
395 |
} |
391 |
if ( mpFactory ) |
396 |
if (mpFactory) |
392 |
{ |
397 |
{ |
393 |
delete mpFactory; |
398 |
delete mpFactory; |
394 |
} |
399 |
} |
395 |
if ( mpCvtCache ) |
400 |
if (mpCvtCache) |
396 |
{ |
401 |
{ |
397 |
delete mpCvtCache; |
402 |
delete mpCvtCache; |
398 |
} |
403 |
} |
399 |
|
404 |
|
400 |
pFontCache_ = (SalFontCache*)NULL; |
405 |
pFontCache_ = (SalFontCache *) NULL; |
401 |
mpFontList = (XlfdStorage*)NULL; |
406 |
mpFontList = (XlfdStorage *) NULL; |
402 |
mpFactory = (AttributeProvider*)NULL; |
407 |
mpFactory = (AttributeProvider *) NULL; |
403 |
mpCvtCache = (SalConverterCache*)NULL; |
408 |
mpCvtCache = (SalConverterCache *) NULL; |
404 |
} |
409 |
} |
405 |
|
410 |
|
406 |
// ---------------------------------------------------------------------------- |
411 |
// ---------------------------------------------------------------------------- |
Lines 409-441
Link Here
|
409 |
// |
414 |
// |
410 |
// ---------------------------------------------------------------------------- |
415 |
// ---------------------------------------------------------------------------- |
411 |
|
416 |
|
412 |
GC |
417 |
GC SalGraphicsData::SelectFont () |
413 |
SalGraphicsData::SelectFont() |
|
|
414 |
{ |
418 |
{ |
415 |
Display *pDisplay = GetXDisplay(); |
419 |
Display * |
416 |
|
420 |
pDisplay = GetXDisplay (); |
417 |
if( !pFontGC_ ) |
|
|
418 |
{ |
419 |
XGCValues values; |
420 |
values.subwindow_mode = IncludeInferiors; |
421 |
values.fill_rule = EvenOddRule; // Pict import/ Gradient |
422 |
values.graphics_exposures = True; |
423 |
values.foreground = nTextPixel_; |
424 |
|
425 |
pFontGC_ = XCreateGC( pDisplay, hDrawable_, |
426 |
GCSubwindowMode | GCFillRule |
427 |
| GCGraphicsExposures | GCForeground, |
428 |
&values ); |
429 |
} |
430 |
|
421 |
|
431 |
if( !bFontGC_ ) |
422 |
if (!pFontGC_) |
432 |
{ |
423 |
{ |
433 |
XSetForeground( pDisplay, pFontGC_, nTextPixel_ ); |
424 |
XGCValues |
434 |
SetClipRegion( pFontGC_ ); |
425 |
values; |
435 |
bFontGC_ = TRUE; |
426 |
values.subwindow_mode = IncludeInferiors; |
436 |
} |
427 |
values.fill_rule = EvenOddRule; // Pict import/ Gradient |
|
|
428 |
values.graphics_exposures = True; |
429 |
values.foreground = nTextPixel_; |
430 |
|
431 |
pFontGC_ = XCreateGC (pDisplay, hDrawable_, |
432 |
GCSubwindowMode | GCFillRule |
433 |
| GCGraphicsExposures | GCForeground, &values); |
434 |
} |
435 |
|
436 |
if (!bFontGC_) |
437 |
{ |
438 |
XSetForeground (pDisplay, pFontGC_, nTextPixel_); |
439 |
SetClipRegion (pFontGC_); |
440 |
bFontGC_ = TRUE; |
441 |
} |
437 |
|
442 |
|
438 |
return pFontGC_; |
443 |
return pFontGC_; |
439 |
} |
444 |
} |
440 |
|
445 |
|
441 |
//-------------------------------------------------------------------------- |
446 |
//-------------------------------------------------------------------------- |
Lines 444-970
Link Here
|
444 |
// This routine is (and should be) called only once, the result should be |
449 |
// This routine is (and should be) called only once, the result should be |
445 |
// stored in some static variable |
450 |
// stored in some static variable |
446 |
|
451 |
|
447 |
static int |
452 |
static int |
448 |
GetMaxFontHeight() |
453 |
GetMaxFontHeight () |
449 |
{ |
454 |
{ |
450 |
#define DEFAULT_MAXFONTHEIGHT 250 |
455 |
#define DEFAULT_MAXFONTHEIGHT 250 |
451 |
|
456 |
|
452 |
int nMaxFontHeight = 0; |
457 |
int |
|
|
458 |
nMaxFontHeight = 0; |
453 |
|
459 |
|
454 |
char *FontHeight = getenv ("SAL_MAXFONTHEIGHT"); |
460 |
char * |
455 |
if (FontHeight) |
461 |
FontHeight = getenv ("SAL_MAXFONTHEIGHT"); |
456 |
nMaxFontHeight = atoi (FontHeight); |
462 |
if (FontHeight) |
|
|
463 |
nMaxFontHeight = atoi (FontHeight); |
457 |
|
464 |
|
458 |
if (nMaxFontHeight <= 0) |
465 |
if (nMaxFontHeight <= 0) |
459 |
nMaxFontHeight = DEFAULT_MAXFONTHEIGHT; |
466 |
nMaxFontHeight = DEFAULT_MAXFONTHEIGHT; |
460 |
|
467 |
|
461 |
return nMaxFontHeight; |
468 |
return nMaxFontHeight; |
462 |
} |
469 |
} |
463 |
|
470 |
|
464 |
void |
471 |
void |
465 |
SalGraphicsData::SetFont( const ImplFontSelectData *pEntry ) |
472 |
SalGraphicsData::SetFont (const ImplFontSelectData * pEntry) |
466 |
{ |
473 |
{ |
467 |
bFontGC_ = FALSE; |
474 |
bFontGC_ = FALSE; |
468 |
xFont_ = NULL; // ->ReleaseRef() |
475 |
xFont_ = NULL; // ->ReleaseRef() |
469 |
aScale_ = Fraction( 1, 1 ); |
476 |
aScale_ = Fraction (1, 1); |
470 |
nFontOrientation_ = pEntry->mnOrientation; |
477 |
nFontOrientation_ = pEntry->mnOrientation; |
471 |
bFontVertical_ = pEntry->mbVertical; |
478 |
bFontVertical_ = pEntry->mbVertical; |
472 |
|
479 |
|
473 |
if( pEntry->mpFontData && pEntry->mpFontData->mpSysData ) |
480 |
if (pEntry->mpFontData && pEntry->mpFontData->mpSysData) |
474 |
{ |
481 |
{ |
475 |
ExtendedXlfd *pSysFont = (ExtendedXlfd*)pEntry->mpFontData->mpSysData; |
482 |
ExtendedXlfd *pSysFont = (ExtendedXlfd *) pEntry->mpFontData->mpSysData; |
476 |
static int nMaxFontHeight = GetMaxFontHeight(); |
483 |
static int nMaxFontHeight = GetMaxFontHeight (); |
477 |
|
484 |
|
478 |
USHORT nH, nW; |
485 |
USHORT nH, nW; |
479 |
if( bWindow_ ) |
486 |
if (bWindow_) |
480 |
{ |
487 |
{ |
481 |
// see BugId #44528# FontWork (-> #45038#) and as well Bug #47127# |
488 |
// see BugId #44528# FontWork (-> #45038#) and as well Bug #47127# |
482 |
if( pEntry->mnHeight > nMaxFontHeight ) |
489 |
if (pEntry->mnHeight > nMaxFontHeight) |
483 |
nH = nMaxFontHeight; |
490 |
nH = nMaxFontHeight; |
484 |
else if( pEntry->mnHeight > 2 ) |
491 |
else if (pEntry->mnHeight > 2) |
485 |
nH = pEntry->mnHeight; |
492 |
nH = pEntry->mnHeight; |
486 |
else |
493 |
else |
487 |
nH = 2; |
494 |
nH = 2; |
488 |
nW = 0; // pEntry->mnWidth; |
495 |
nW = 0; // pEntry->mnWidth; |
489 |
} |
496 |
} |
490 |
else |
497 |
else |
491 |
{ |
498 |
{ |
492 |
nH = pEntry->mnHeight; |
499 |
nH = pEntry->mnHeight; |
493 |
nW = pEntry->mnWidth; |
500 |
nW = pEntry->mnWidth; |
494 |
} |
501 |
} |
495 |
|
502 |
|
496 |
xFont_ = GetDisplay()->GetFont( pSysFont, nH ); |
503 |
xFont_ = GetDisplay ()->GetFont (pSysFont, nH); |
497 |
if( pEntry->mnHeight > nMaxFontHeight || pEntry->mnHeight < 2 ) |
504 |
if (pEntry->mnHeight > nMaxFontHeight || pEntry->mnHeight < 2) |
498 |
aScale_ = Fraction( pEntry->mnHeight, nH ); |
505 |
aScale_ = Fraction (pEntry->mnHeight, nH); |
499 |
} |
506 |
} |
500 |
else |
507 |
else |
501 |
{ |
508 |
{ |
502 |
#ifdef DEBUG |
509 |
#ifdef DEBUG |
503 |
// XXX Fix me: provide a fallback for poor font installations |
510 |
// XXX Fix me: provide a fallback for poor font installations |
504 |
// we may be reach this if no font matches the GUI font |
511 |
// we may be reach this if no font matches the GUI font |
505 |
// MS Sans Serif;Geneva;Helv;WarpSans;Dialog;Lucida; ... */ |
512 |
// MS Sans Serif;Geneva;Helv;WarpSans;Dialog;Lucida; ... */ |
506 |
fprintf( stderr, "SalGraphicsData::SetFont: Invalid Font Selection\n" ); |
513 |
fprintf (stderr, "SalGraphicsData::SetFont: Invalid Font Selection\n"); |
507 |
#endif |
514 |
#endif |
508 |
} |
515 |
} |
509 |
} |
516 |
} |
510 |
|
517 |
|
511 |
//-------------------------------------------------------------------------- |
518 |
//-------------------------------------------------------------------------- |
512 |
|
519 |
|
513 |
static sal_Unicode |
520 |
static sal_Unicode |
514 |
SwapBytes( const sal_Unicode nIn ) |
521 |
SwapBytes (const sal_Unicode nIn) |
515 |
{ |
522 |
{ |
516 |
return ((nIn >> 8) & 0x00ff) | ((nIn << 8) & 0xff00); |
523 |
return ((nIn >> 8) & 0x00ff) | ((nIn << 8) & 0xff00); |
517 |
} |
524 |
} |
518 |
|
525 |
|
519 |
|
526 |
|
520 |
// draw string in a specific multibyte encoding |
527 |
// draw string in a specific multibyte encoding |
521 |
static void |
528 |
static void |
522 |
ConvertTextItem16( XTextItem16* pTextItem, |
529 |
ConvertTextItem16 (XTextItem16 * pTextItem, |
523 |
SalConverterCache* pCvt, rtl_TextEncoding nEncoding ) |
530 |
SalConverterCache * pCvt, rtl_TextEncoding nEncoding) |
524 |
{ |
531 |
{ |
525 |
if ( pTextItem && pTextItem->nchars > 0 ) |
532 |
if (pTextItem && pTextItem->nchars > 0) |
526 |
{ |
533 |
{ |
527 |
// convert the string into the font encoding |
534 |
// convert the string into the font encoding |
528 |
sal_Size nSize; |
535 |
sal_Size nSize; |
529 |
sal_Size nBufferSize = pTextItem->nchars * 2; |
536 |
sal_Size nBufferSize = pTextItem->nchars * 2; |
530 |
sal_Char *pBuffer = (sal_Char*)alloca( nBufferSize ); |
537 |
sal_Char *pBuffer = (sal_Char *) alloca (nBufferSize); |
531 |
|
538 |
|
532 |
nSize = ConvertStringUTF16( (sal_Unicode*)pTextItem->chars, pTextItem->nchars, |
539 |
nSize = |
533 |
pBuffer, nBufferSize, pCvt->GetU2TConverter(nEncoding)); |
540 |
ConvertStringUTF16 ((sal_Unicode *) pTextItem->chars, |
534 |
|
541 |
pTextItem->nchars, pBuffer, nBufferSize, |
535 |
sal_Char *pTextChars = (sal_Char*)pTextItem->chars; |
542 |
pCvt->GetU2TConverter (nEncoding)); |
536 |
int n = 0, m = 0; |
543 |
|
537 |
|
544 |
sal_Char *pTextChars = (sal_Char *) pTextItem->chars; |
538 |
if ( nEncoding == RTL_TEXTENCODING_GB_2312 |
545 |
int n = 0, m = 0; |
539 |
|| nEncoding == RTL_TEXTENCODING_GBT_12345 |
546 |
|
540 |
|| nEncoding == RTL_TEXTENCODING_GBK |
547 |
if (nEncoding == RTL_TEXTENCODING_GB_2312 |
541 |
|| nEncoding == RTL_TEXTENCODING_BIG5 ) |
548 |
|| nEncoding == RTL_TEXTENCODING_GBT_12345 |
542 |
{ |
549 |
|| nEncoding == RTL_TEXTENCODING_GBK |
543 |
// GB and Big5 needs special treatment since chars can be single or |
550 |
|| nEncoding == RTL_TEXTENCODING_BIG5) |
544 |
// double byte: encoding is |
551 |
{ |
545 |
// [ 0x00 - 0x7f ] | [ 0x81 - 0xfe ] [ 0x40 - 0x7e 0x80 - 0xfe ] |
552 |
// GB and Big5 needs special treatment since chars can be single or |
546 |
while ( n < nSize ) |
553 |
// double byte: encoding is |
547 |
{ |
554 |
// [ 0x00 - 0x7f ] | [ 0x81 - 0xfe ] [ 0x40 - 0x7e 0x80 - 0xfe ] |
548 |
if ( (unsigned char)pBuffer[ n ] < 0x80 ) |
555 |
while (n < nSize) |
549 |
{ |
556 |
{ |
550 |
pTextChars[ m++ ] = 0x0; |
557 |
if ((unsigned char) pBuffer[n] & 0x80) |
551 |
pTextChars[ m++ ] = pBuffer[ n++ ]; |
558 |
{ |
552 |
} |
559 |
switch (nEncoding) |
553 |
else |
560 |
{ |
554 |
{ |
561 |
case RTL_TEXTENCODING_GB_2312: //The font are store in cjk iso2022 mode do some translation |
555 |
pTextChars[ m++ ] = pBuffer[ n++ ]; |
562 |
pTextChars[m++] = pBuffer[n++] & 0x7f; |
556 |
pTextChars[ m++ ] = pBuffer[ n++ ]; |
563 |
pTextChars[m++] = pBuffer[n++] & 0x7f; |
557 |
} |
564 |
break; |
558 |
} |
565 |
|
559 |
pTextItem->nchars = m / 2; |
566 |
default: |
560 |
} |
567 |
pTextChars[m++] = pBuffer[n++]; |
561 |
else |
568 |
pTextChars[m++] = 0x0; |
562 |
if ( pCvt->IsSingleByteEncoding(nEncoding) ) |
569 |
break; |
563 |
{ |
570 |
} |
564 |
// Single Byte encoding has to be padded |
571 |
} |
565 |
while ( n < nSize ) |
572 |
else |
566 |
{ |
573 |
{ |
567 |
pTextChars[ m++ ] = 0x0; |
574 |
pTextChars[m++] = pBuffer[n++]; |
568 |
pTextChars[ m++ ] = pBuffer[ n++ ]; |
575 |
pTextChars[m++] = pBuffer[n++]; |
569 |
} |
576 |
} |
570 |
pTextItem->nchars = nSize; |
577 |
} |
571 |
} |
578 |
pTextItem->nchars = m / 2; |
572 |
else |
579 |
} |
573 |
{ |
580 |
else if (pCvt->IsSingleByteEncoding (nEncoding)) |
574 |
while ( n < nSize ) |
581 |
{ |
575 |
{ |
582 |
// Single Byte encoding has to be padded |
576 |
pTextChars[ m++ ] = pBuffer[ n++ ]; |
583 |
while (n < nSize) |
577 |
} |
584 |
{ |
578 |
pTextItem->nchars = nSize / 2; |
585 |
pTextChars[m++] = 0x0; |
579 |
} |
586 |
pTextChars[m++] = pBuffer[n++]; |
|
|
587 |
} |
588 |
pTextItem->nchars = nSize; |
589 |
} |
590 |
else |
591 |
{ |
592 |
while (n < nSize) |
593 |
{ |
594 |
pTextChars[m++] = pBuffer[n++]; |
595 |
} |
596 |
pTextItem->nchars = nSize / 2; |
580 |
} |
597 |
} |
|
|
598 |
} |
581 |
} |
599 |
} |
582 |
|
600 |
|
583 |
// XXX this is a hack since XPrinter is not multibyte capable |
601 |
// XXX this is a hack since XPrinter is not multibyte capable |
584 |
// XXX for printing this routine is called for each character |
602 |
// XXX for printing this routine is called for each character |
585 |
void |
603 |
void |
586 |
XPrinterDrawText16( Display* pDisplay, Drawable nDrawable, GC nGC, |
604 |
XPrinterDrawText16 (Display * pDisplay, Drawable nDrawable, GC nGC, |
587 |
int nX, int nY, int nAngle, XTextItem16 *pTextItem16, int nItem ) |
605 |
int nX, int nY, int nAngle, XTextItem16 * pTextItem16, |
588 |
{ |
606 |
int nItem) |
589 |
// convert XTextItem16 to XTextItem |
607 |
{ |
590 |
XTextItem *pTextItem = (XTextItem*)alloca( nItem * sizeof(XTextItem) ); |
608 |
// convert XTextItem16 to XTextItem |
591 |
|
609 |
XTextItem *pTextItem = (XTextItem *) alloca (nItem * sizeof (XTextItem)); |
592 |
for ( int nCurItem = 0; nCurItem < nItem; nCurItem++ ) |
610 |
|
593 |
{ |
611 |
for (int nCurItem = 0; nCurItem < nItem; nCurItem++) |
594 |
int nChars = pTextItem16[ nCurItem ].nchars; |
612 |
{ |
595 |
char* pDstCharPtr = (char*)alloca( nChars * sizeof(char) ); |
613 |
int nChars = pTextItem16[nCurItem].nchars; |
596 |
XChar2b* pSrcCharPtr = pTextItem16[ nCurItem ].chars; |
614 |
char *pDstCharPtr = (char *) alloca (nChars * sizeof (char)); |
597 |
|
615 |
XChar2b *pSrcCharPtr = pTextItem16[nCurItem].chars; |
598 |
pTextItem[ nCurItem ].chars = pDstCharPtr; |
616 |
|
599 |
pTextItem[ nCurItem ].nchars = nChars; |
617 |
pTextItem[nCurItem].chars = pDstCharPtr; |
600 |
pTextItem[ nCurItem ].delta = pTextItem16[ nCurItem ].delta; |
618 |
pTextItem[nCurItem].nchars = nChars; |
601 |
pTextItem[ nCurItem ].font = pTextItem16[ nCurItem ].font; |
619 |
pTextItem[nCurItem].delta = pTextItem16[nCurItem].delta; |
602 |
|
620 |
pTextItem[nCurItem].font = pTextItem16[nCurItem].font; |
603 |
for ( int nCurChar = 0; |
621 |
|
604 |
nCurChar < nChars; |
622 |
for (int nCurChar = 0; |
605 |
nCurChar++, pDstCharPtr++, pSrcCharPtr++ ) |
623 |
nCurChar < nChars; nCurChar++, pDstCharPtr++, pSrcCharPtr++) |
606 |
{ |
624 |
{ |
607 |
*pDstCharPtr = (char)pSrcCharPtr->byte2; |
625 |
*pDstCharPtr = (char) pSrcCharPtr->byte2; |
608 |
} |
626 |
} |
609 |
} |
627 |
} |
610 |
|
628 |
|
611 |
if ( nAngle != 0 ) |
629 |
if (nAngle != 0) |
612 |
{ |
630 |
{ |
613 |
for ( int nCurItem = 0; nCurItem < nItem; nCurItem++ ) |
631 |
for (int nCurItem = 0; nCurItem < nItem; nCurItem++) |
614 |
{ |
632 |
{ |
615 |
// XXX FIXME this is broken, because nX and nY is not sufficiently updated |
633 |
// XXX FIXME this is broken, because nX and nY is not sufficiently updated |
616 |
XSetFont( pDisplay, nGC, pTextItem[ nItem ].font ); |
634 |
XSetFont (pDisplay, nGC, pTextItem[nItem].font); |
617 |
if ( XSalCanDrawRotString(pDisplay, nGC) ) |
635 |
if (XSalCanDrawRotString (pDisplay, nGC)) |
618 |
{ |
636 |
{ |
619 |
XSalDrawRotString( pDisplay, nDrawable, nGC, nX, nY, |
637 |
XSalDrawRotString (pDisplay, nDrawable, nGC, nX, nY, |
620 |
pTextItem[ nCurItem ].chars, pTextItem[ nCurItem ].nchars, nAngle ); |
638 |
pTextItem[nCurItem].chars, |
621 |
} |
639 |
pTextItem[nCurItem].nchars, nAngle); |
622 |
else |
640 |
} |
623 |
{ |
641 |
else |
624 |
XDrawString( pDisplay, nDrawable, nGC, nX, nY, |
642 |
{ |
625 |
pTextItem[ nCurItem ].chars, pTextItem[ nCurItem ].nchars ); |
643 |
XDrawString (pDisplay, nDrawable, nGC, nX, nY, |
626 |
} |
644 |
pTextItem[nCurItem].chars, |
627 |
} |
645 |
pTextItem[nCurItem].nchars); |
628 |
} |
646 |
} |
629 |
else |
647 |
} |
630 |
{ |
648 |
} |
631 |
XDrawText( pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem ); |
649 |
else |
632 |
} |
650 |
{ |
|
|
651 |
XDrawText (pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem); |
652 |
} |
633 |
} |
653 |
} |
634 |
|
654 |
|
635 |
// draw string vertically |
655 |
// draw string vertically |
636 |
static void |
656 |
static void |
637 |
DrawVerticalString ( Display *pDisplay, Drawable nDrawable, GC nGC, |
657 |
DrawVerticalString (Display * pDisplay, Drawable nDrawable, GC nGC, |
638 |
int nX, int nY, const sal_Unicode *pStr, int nLength, |
658 |
int nX, int nY, const sal_Unicode * pStr, int nLength, |
639 |
ExtendedFontStruct *pFont ) |
659 |
ExtendedFontStruct * pFont) |
640 |
{ |
660 |
{ |
641 |
VerticalTextItem** pTextItems; |
661 |
VerticalTextItem **pTextItems; |
642 |
int nNumItem = pFont->GetVerticalTextItems( pStr, nLength, RTL_TEXTENCODING_UNICODE, |
662 |
int nNumItem = |
643 |
pStr, pTextItems ); |
663 |
pFont->GetVerticalTextItems (pStr, nLength, RTL_TEXTENCODING_UNICODE, |
644 |
|
664 |
pStr, pTextItems); |
645 |
for ( int nIdx = 0; nIdx < nNumItem; nIdx++ ) |
665 |
|
646 |
{ |
666 |
for (int nIdx = 0; nIdx < nNumItem; nIdx++) |
647 |
if ( pTextItems[nIdx]->mpXFontStruct == NULL ) |
667 |
{ |
648 |
continue; |
668 |
if (pTextItems[nIdx]->mpXFontStruct == NULL) |
649 |
|
669 |
continue; |
650 |
XSetFont( pDisplay, nGC, pTextItems[nIdx]->mpXFontStruct->fid ); |
670 |
|
651 |
for ( int nChar = 0; nChar < pTextItems[nIdx]->mnLength; nChar++ ) |
671 |
XSetFont (pDisplay, nGC, pTextItems[nIdx]->mpXFontStruct->fid); |
652 |
{ |
672 |
for (int nChar = 0; nChar < pTextItems[nIdx]->mnLength; nChar++) |
653 |
XDrawString16( pDisplay, nDrawable, nGC, |
673 |
{ |
654 |
nX + pTextItems[nIdx]->mnTransX, |
674 |
XDrawString16 (pDisplay, nDrawable, nGC, |
655 |
nY + pTextItems[nIdx]->mnTransY, |
675 |
nX + pTextItems[nIdx]->mnTransX, |
656 |
(XChar2b*)(pTextItems[nIdx]->mpString + nChar), 1 ); |
676 |
nY + pTextItems[nIdx]->mnTransY, |
657 |
nY += (pTextItems[nIdx]->mbFixed ? |
677 |
(XChar2b *) (pTextItems[nIdx]->mpString + nChar), 1); |
658 |
pTextItems[nIdx]->mnFixedAdvance : pTextItems[nIdx]->mpAdvanceAry[nChar]); |
678 |
nY += (pTextItems[nIdx]->mbFixed ? |
659 |
} |
679 |
pTextItems[nIdx]->mnFixedAdvance : pTextItems[nIdx]-> |
660 |
} |
680 |
mpAdvanceAry[nChar]); |
661 |
|
681 |
} |
662 |
for (int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++) |
682 |
} |
663 |
{ |
683 |
|
664 |
delete( pTextItems[nIdx2] ); |
684 |
for (int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++) |
665 |
} |
685 |
{ |
666 |
free( pTextItems ); |
686 |
delete (pTextItems[nIdx2]); |
|
|
687 |
} |
688 |
free (pTextItems); |
667 |
} |
689 |
} |
668 |
|
690 |
|
669 |
struct VTextItemExt |
691 |
struct VTextItemExt |
670 |
{ |
692 |
{ |
671 |
rtl_TextEncoding mnEncoding; |
693 |
rtl_TextEncoding mnEncoding; |
672 |
const sal_Unicode* mpString; |
694 |
const sal_Unicode *mpString; |
673 |
}; |
695 |
}; |
674 |
|
696 |
|
675 |
static void |
697 |
static void |
676 |
DrawVerticalTextItem( Display *pDisplay, Drawable nDrawable, GC nGC, |
698 |
DrawVerticalTextItem (Display * pDisplay, Drawable nDrawable, GC nGC, |
677 |
int nX, int nY, XTextItem16* pTextItem, int nItem, |
699 |
int nX, int nY, XTextItem16 * pTextItem, int nItem, |
678 |
VTextItemExt* pVTextItemExt, ExtendedFontStruct* pFont ) |
700 |
VTextItemExt * pVTextItemExt, |
679 |
{ |
701 |
ExtendedFontStruct * pFont) |
680 |
for ( int nItemIdx = 0; nItemIdx < nItem; nItemIdx++ ) |
702 |
{ |
681 |
{ |
703 |
for (int nItemIdx = 0; nItemIdx < nItem; nItemIdx++) |
682 |
VerticalTextItem** pVTextItems; |
704 |
{ |
683 |
int nNumItem = pFont->GetVerticalTextItems( pVTextItemExt[nItemIdx].mpString, |
705 |
VerticalTextItem **pVTextItems; |
684 |
pTextItem[nItemIdx].nchars, |
706 |
int nNumItem = |
685 |
pVTextItemExt[nItemIdx].mnEncoding, |
707 |
pFont->GetVerticalTextItems (pVTextItemExt[nItemIdx].mpString, |
686 |
(sal_Unicode *)pTextItem[nItemIdx].chars, |
708 |
pTextItem[nItemIdx].nchars, |
687 |
pVTextItems ); |
709 |
pVTextItemExt[nItemIdx].mnEncoding, |
688 |
for ( int nIdx = 0; nIdx < nNumItem; nIdx++ ) |
710 |
(sal_Unicode *) pTextItem[nItemIdx].chars, |
689 |
{ |
711 |
pVTextItems); |
690 |
if ( pVTextItems[nIdx]->mpXFontStruct == NULL ) |
712 |
for (int nIdx = 0; nIdx < nNumItem; nIdx++) |
691 |
continue; |
713 |
{ |
692 |
|
714 |
if (pVTextItems[nIdx]->mpXFontStruct == NULL) |
693 |
XSetFont( pDisplay, nGC, pVTextItems[nIdx]->mpXFontStruct->fid ); |
715 |
continue; |
694 |
for (int nChar = 0; nChar < pVTextItems[nIdx]->mnLength; nChar++ ) |
716 |
|
695 |
{ |
717 |
XSetFont (pDisplay, nGC, pVTextItems[nIdx]->mpXFontStruct->fid); |
696 |
XDrawString16( pDisplay, nDrawable, nGC, |
718 |
for (int nChar = 0; nChar < pVTextItems[nIdx]->mnLength; nChar++) |
697 |
nX + pVTextItems[nIdx]->mnTransX, |
719 |
{ |
698 |
nY + pVTextItems[nIdx]->mnTransY, |
720 |
XDrawString16 (pDisplay, nDrawable, nGC, |
699 |
(XChar2b*)(pVTextItems[nIdx]->mpString + nChar), 1 ); |
721 |
nX + pVTextItems[nIdx]->mnTransX, |
700 |
nY += (pVTextItems[nIdx]->mbFixed ? |
722 |
nY + pVTextItems[nIdx]->mnTransY, |
701 |
pVTextItems[nIdx]->mnFixedAdvance : pVTextItems[nIdx]->mpAdvanceAry[nChar]); |
723 |
(XChar2b *) (pVTextItems[nIdx]->mpString + |
702 |
} |
724 |
nChar), 1); |
703 |
} |
725 |
nY += |
704 |
for ( int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++ ) |
726 |
(pVTextItems[nIdx]->mbFixed ? pVTextItems[nIdx]-> |
705 |
{ |
727 |
mnFixedAdvance : pVTextItems[nIdx]->mpAdvanceAry[nChar]); |
706 |
delete( pVTextItems[nIdx2] ); |
728 |
} |
707 |
} |
|
|
708 |
free( pVTextItems ); |
709 |
} |
729 |
} |
|
|
730 |
for (int nIdx2 = 0; nIdx2 < nNumItem; nIdx2++) |
731 |
{ |
732 |
delete (pVTextItems[nIdx2]); |
733 |
} |
734 |
free (pVTextItems); |
735 |
} |
710 |
} |
736 |
} |
711 |
|
737 |
|
712 |
// draw string in one of the fonts / encodings that are available in the |
738 |
// draw string in one of the fonts / encodings that are available in the |
713 |
// extended font |
739 |
// extended font |
714 |
static void |
740 |
static void |
715 |
DrawString( Display *pDisplay, Drawable nDrawable, GC nGC, |
741 |
DrawString (Display * pDisplay, Drawable nDrawable, GC nGC, |
716 |
int nX, int nY, const sal_Unicode *pStr, int nLength, int nAngle, BOOL bVertical, |
742 |
int nX, int nY, const sal_Unicode * pStr, int nLength, int nAngle, |
717 |
SalConverterCache *pCvt, ExtendedFontStruct *pFont ) |
743 |
BOOL bVertical, SalConverterCache * pCvt, |
718 |
{ |
744 |
ExtendedFontStruct * pFont) |
719 |
// sanity check |
745 |
{ |
720 |
if ( pFont == NULL || nLength == 0 ) |
746 |
// sanity check |
721 |
return; |
747 |
if (pFont == NULL || nLength == 0) |
|
|
748 |
return; |
749 |
|
750 |
rtl_TextEncoding nAsciiEnc = pFont->GetAsciiEncoding (); |
751 |
|
752 |
if (nAsciiEnc == RTL_TEXTENCODING_UNICODE) |
753 |
{ |
754 |
if (bVertical) |
755 |
DrawVerticalString (pDisplay, nDrawable, nGC, nX, nY, pStr, nLength, |
756 |
pFont); |
757 |
else |
758 |
{ |
759 |
|
760 |
// plain Unicode, can handle all chars and can be handled straight forward |
761 |
XFontStruct *pFontStruct = pFont->GetFontStruct (nAsciiEnc); |
762 |
|
763 |
if (pFontStruct == NULL) |
764 |
return; |
765 |
|
766 |
XSetFont (pDisplay, nGC, pFontStruct->fid); |
767 |
|
768 |
#ifdef OSL_LITENDIAN |
769 |
sal_Unicode *pBuffer = |
770 |
(sal_Unicode *) alloca (nLength * sizeof (sal_Unicode)); |
771 |
for (int i = 0; i < nLength; i++) |
772 |
pBuffer[i] = SwapBytes (pStr[i]); |
773 |
#else |
774 |
sal_Unicode *pBuffer = const_cast < sal_Unicode * >(pStr); |
775 |
#endif |
722 |
|
776 |
|
723 |
rtl_TextEncoding nAsciiEnc = pFont->GetAsciiEncoding(); |
777 |
XDrawString16 (pDisplay, nDrawable, nGC, nX, nY, |
|
|
778 |
(XChar2b *) pBuffer, nLength); |
779 |
} |
780 |
} |
781 |
else |
782 |
{ |
783 |
// convert the string to a XTextItem16 with each item chars having the |
784 |
// encoding matching the font of fontid |
785 |
XTextItem16 *pTextItem = |
786 |
(XTextItem16 *) alloca (nLength * sizeof (XTextItem16)); |
787 |
XChar2b *pMBChar = (XChar2b *) alloca (nLength * sizeof (XChar2b)); |
788 |
memcpy (pMBChar, pStr, nLength * sizeof (XChar2b)); |
724 |
|
789 |
|
725 |
if ( nAsciiEnc == RTL_TEXTENCODING_UNICODE ) |
790 |
rtl_TextEncoding nEncoding = nAsciiEnc; |
726 |
{ |
791 |
XFontStruct *pFontStruct = pFont->GetFontStruct (nEncoding); |
727 |
if ( bVertical ) |
|
|
728 |
DrawVerticalString( pDisplay, nDrawable, nGC, nX, nY, pStr, nLength, pFont ); |
729 |
else |
730 |
{ |
731 |
|
792 |
|
732 |
// plain Unicode, can handle all chars and can be handled straight forward |
793 |
if (pFontStruct == NULL) |
733 |
XFontStruct* pFontStruct = pFont->GetFontStruct( nAsciiEnc ); |
794 |
return; |
734 |
|
795 |
|
735 |
if ( pFontStruct == NULL ) |
796 |
VTextItemExt *pVTextItemExt; |
736 |
return; |
797 |
if (bVertical) |
737 |
|
798 |
pVTextItemExt = |
738 |
XSetFont( pDisplay, nGC, pFontStruct->fid ); |
799 |
(VTextItemExt *) alloca (nLength * sizeof (VTextItemExt)); |
739 |
|
|
|
740 |
#ifdef OSL_LITENDIAN |
741 |
sal_Unicode *pBuffer = (sal_Unicode*)alloca( nLength * sizeof(sal_Unicode) ); |
742 |
for ( int i = 0; i < nLength; i++ ) |
743 |
pBuffer[ i ] = SwapBytes(pStr[ i ]) ; |
744 |
#else |
745 |
sal_Unicode *pBuffer = const_cast<sal_Unicode*>(pStr); |
746 |
#endif |
747 |
|
800 |
|
748 |
XDrawString16( pDisplay, nDrawable, nGC, nX, nY, (XChar2b*)pBuffer, nLength ); |
801 |
for (int nChar = 0, nItem = -1; nChar < nLength; nChar++) |
749 |
} |
|
|
750 |
} |
751 |
else |
752 |
{ |
802 |
{ |
753 |
// convert the string to a XTextItem16 with each item chars having the |
803 |
rtl_TextEncoding nOldEnc = nEncoding; |
754 |
// encoding matching the font of fontid |
804 |
pFont->GetFontStruct (pStr[nChar], &nEncoding, &pFontStruct, pCvt); |
755 |
XTextItem16 *pTextItem = (XTextItem16*)alloca( nLength * sizeof(XTextItem16) ); |
|
|
756 |
XChar2b *pMBChar = (XChar2b*)alloca( nLength * sizeof(XChar2b) ); |
757 |
memcpy( pMBChar, pStr, nLength * sizeof(XChar2b) ); |
758 |
|
759 |
rtl_TextEncoding nEncoding = nAsciiEnc; |
760 |
XFontStruct* pFontStruct = pFont->GetFontStruct( nEncoding ); |
761 |
|
762 |
if ( pFontStruct == NULL ) |
763 |
return; |
764 |
|
805 |
|
765 |
VTextItemExt* pVTextItemExt; |
806 |
if (pFontStruct == NULL) |
766 |
if ( bVertical ) |
807 |
continue; |
767 |
pVTextItemExt = (VTextItemExt*)alloca( nLength * sizeof(VTextItemExt) ); |
|
|
768 |
|
808 |
|
769 |
for ( int nChar = 0, nItem = -1; nChar < nLength; nChar++ ) |
809 |
if ((nItem != -1) && (pFontStruct->fid == pTextItem[nItem].font)) |
770 |
{ |
810 |
{ |
771 |
rtl_TextEncoding nOldEnc = nEncoding; |
811 |
pTextItem[nItem].nchars += 1; |
772 |
pFont->GetFontStruct( pStr[nChar], &nEncoding, &pFontStruct, pCvt ); |
812 |
} |
|
|
813 |
else |
814 |
{ |
815 |
if (nItem != -1) |
816 |
ConvertTextItem16 (&pTextItem[nItem], pCvt, nOldEnc); |
773 |
|
817 |
|
774 |
if ( pFontStruct == NULL ) |
818 |
++nItem; |
775 |
continue; |
|
|
776 |
|
819 |
|
777 |
if ( (nItem != -1) && (pFontStruct->fid == pTextItem[ nItem ].font) ) |
820 |
pTextItem[nItem].chars = pMBChar + nChar; |
778 |
{ |
821 |
pTextItem[nItem].delta = 0; |
779 |
pTextItem[ nItem ].nchars += 1; |
822 |
pTextItem[nItem].font = pFontStruct->fid; |
780 |
} |
823 |
pTextItem[nItem].nchars = 1; |
781 |
else |
|
|
782 |
{ |
783 |
if ( nItem != -1 ) |
784 |
ConvertTextItem16( &pTextItem[ nItem ], pCvt, nOldEnc ); |
785 |
|
786 |
++nItem; |
787 |
|
788 |
pTextItem[ nItem ].chars = pMBChar + nChar; |
789 |
pTextItem[ nItem ].delta = 0; |
790 |
pTextItem[ nItem ].font = pFontStruct->fid; |
791 |
pTextItem[ nItem ].nchars = 1; |
792 |
|
793 |
if ( bVertical ) |
794 |
{ |
795 |
pVTextItemExt[ nItem ].mnEncoding = nEncoding; |
796 |
pVTextItemExt[ nItem ].mpString = pStr + nChar; |
797 |
} |
798 |
} |
799 |
} |
800 |
ConvertTextItem16( &pTextItem[ nItem ], pCvt, nEncoding ); |
801 |
++nItem; |
802 |
|
824 |
|
803 |
if ( bVertical ) |
825 |
if (bVertical) |
804 |
{ |
826 |
{ |
805 |
pVTextItemExt[ nItem - 1 ].mnEncoding = nEncoding; |
827 |
pVTextItemExt[nItem].mnEncoding = nEncoding; |
806 |
DrawVerticalTextItem( pDisplay, nDrawable, nGC, nX, nY, |
828 |
pVTextItemExt[nItem].mpString = pStr + nChar; |
807 |
pTextItem, nItem, pVTextItemExt, pFont ); |
|
|
808 |
free( pVTextItemExt ); |
809 |
} |
829 |
} |
810 |
else |
830 |
} |
811 |
{ |
|
|
812 |
if ( XSalIsDisplay( pDisplay ) ) |
813 |
XDrawText16( pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem ); |
814 |
else |
815 |
XPrinterDrawText16( pDisplay, nDrawable, nGC, nX, nY, nAngle, |
816 |
pTextItem, nItem ); |
817 |
} |
818 |
} |
831 |
} |
|
|
832 |
ConvertTextItem16 (&pTextItem[nItem], pCvt, nEncoding); |
833 |
++nItem; |
834 |
|
835 |
if (bVertical) |
836 |
{ |
837 |
pVTextItemExt[nItem - 1].mnEncoding = nEncoding; |
838 |
DrawVerticalTextItem (pDisplay, nDrawable, nGC, nX, nY, |
839 |
pTextItem, nItem, pVTextItemExt, pFont); |
840 |
free (pVTextItemExt); |
841 |
} |
842 |
else |
843 |
{ |
844 |
if (XSalIsDisplay (pDisplay)) |
845 |
XDrawText16 (pDisplay, nDrawable, nGC, nX, nY, pTextItem, nItem); |
846 |
else |
847 |
XPrinterDrawText16 (pDisplay, nDrawable, nGC, nX, nY, nAngle, |
848 |
pTextItem, nItem); |
849 |
} |
850 |
} |
819 |
} |
851 |
} |
820 |
|
852 |
|
821 |
//-------------------------------------------------------------------------- |
853 |
//-------------------------------------------------------------------------- |
822 |
|
854 |
|
823 |
void |
855 |
void |
824 |
SalGraphicsData::DrawText( long nX, long nY, |
856 |
SalGraphicsData::DrawText (long nX, long nY, |
825 |
const sal_Unicode *pStr, USHORT nLen ) |
857 |
const sal_Unicode * pStr, USHORT nLen) |
826 |
{ |
858 |
{ |
827 |
#ifndef PRINTER_DUMMY |
859 |
#ifndef PRINTER_DUMMY |
828 |
if( bPrinter_ ) |
860 |
if (bPrinter_) |
829 |
FaxPhoneComment( GetXDisplay(), pStr, nLen ); |
861 |
FaxPhoneComment (GetXDisplay (), pStr, nLen); |
830 |
#endif |
862 |
#endif |
|
|
863 |
|
864 |
#ifdef __notdef__ |
865 |
// XXX Fix me this part is not unicode / multibyte aware |
831 |
|
866 |
|
832 |
#ifdef __notdef__ |
867 |
// Bug: #45670# |
833 |
// XXX Fix me this part is not unicode / multibyte aware |
868 |
// some monospace ISO8859-1 fonts have a hole between chars 128 and 159 |
|
|
869 |
// some applications assume these characters have also the default width |
870 |
if (!bPrinter_ && PITCH_FIXED == xFont_->GetFont ()->mePitch && nLen > 1) |
871 |
{ |
872 |
XFontStruct *pXFS = GetFontInfo (); |
873 |
long nWidth = xFont_->GetDim ()->GetWidth (); |
834 |
|
874 |
|
835 |
// Bug: #45670# |
875 |
if (xFont_->GetFixedWidth () != nWidth |
836 |
// some monospace ISO8859-1 fonts have a hole between chars 128 and 159 |
876 |
|| xFont_->GetDefaultWidth () != nWidth) |
837 |
// some applications assume these characters have also the default width |
|
|
838 |
if( ! bPrinter_ && |
839 |
PITCH_FIXED == xFont_->GetFont()->mePitch && |
840 |
nLen > 1 ) |
841 |
{ |
877 |
{ |
842 |
XFontStruct *pXFS = GetFontInfo(); |
878 |
unsigned int min_char = pXFS->min_char_or_byte2; |
843 |
long nWidth = xFont_->GetDim()->GetWidth(); |
879 |
unsigned int max_char = pXFS->max_char_or_byte2; |
|
|
880 |
XCharStruct *pXCS = pXFS->per_char - min_char; |
881 |
|
882 |
for (USHORT i = 0; i < nLen - 1; i++) |
883 |
{ |
884 |
unsigned int c = ((unsigned char *) pStr)[i]; |
885 |
|
886 |
long nW = c < min_char || c > max_char || !pXFS->per_char |
887 |
? xFont_->GetDefaultWidth () : pXCS[c].width; |
844 |
|
888 |
|
845 |
if( xFont_->GetFixedWidth() != nWidth |
889 |
if (nW != nWidth) |
846 |
|| xFont_->GetDefaultWidth() != nWidth ) |
|
|
847 |
{ |
890 |
{ |
848 |
unsigned int min_char = pXFS->min_char_or_byte2; |
891 |
long *pDXAry = new long[nLen]; |
849 |
unsigned int max_char = pXFS->max_char_or_byte2; |
892 |
|
850 |
XCharStruct *pXCS = pXFS->per_char - min_char; |
893 |
for (i = 0; i < nLen; i++) |
851 |
|
894 |
pDXAry[i] = nWidth * (i + 1); |
852 |
for( USHORT i = 0; i < nLen-1; i++ ) |
895 |
|
853 |
{ |
896 |
DrawText (nX, nY, pStr, nLen, pDXAry); |
854 |
unsigned int c = ((unsigned char*)pStr)[i]; |
897 |
|
855 |
|
898 |
delete pDXAry; |
856 |
long nW = c < min_char || c > max_char || ! pXFS->per_char |
899 |
|
857 |
? xFont_->GetDefaultWidth() |
900 |
return; |
858 |
: pXCS[c].width; |
|
|
859 |
|
860 |
if( nW != nWidth ) |
861 |
{ |
862 |
long *pDXAry = new long[nLen]; |
863 |
|
864 |
for( i = 0; i < nLen; i++ ) |
865 |
pDXAry[i] = nWidth * (i+1); |
866 |
|
867 |
DrawText( nX, nY, pStr, nLen, pDXAry ); |
868 |
|
869 |
delete pDXAry; |
870 |
|
871 |
return; |
872 |
} |
873 |
} |
874 |
} |
901 |
} |
|
|
902 |
} |
875 |
} |
903 |
} |
|
|
904 |
} |
905 |
|
906 |
#endif /* __notdef__ */ |
876 |
|
907 |
|
877 |
#endif /* __notdef__ */ |
908 |
Display *pDisplay = GetXDisplay (); |
878 |
|
909 |
SalConverterCache *pCvt = GetDisplay ()->GetConverter (); |
879 |
Display *pDisplay = GetXDisplay(); |
910 |
GC pGC = SelectFont (); |
880 |
SalConverterCache *pCvt = GetDisplay()->GetConverter(); |
911 |
|
881 |
GC pGC = SelectFont(); |
912 |
DrawString (pDisplay, hDrawable_, pGC, nX, nY, |
882 |
|
913 |
pStr, nLen, nFontOrientation_ * 64 / 10, bFontVertical_, pCvt, |
883 |
DrawString( pDisplay, hDrawable_, pGC, nX, nY, |
914 |
xFont_); |
884 |
pStr, nLen, nFontOrientation_ * 64 / 10, bFontVertical_, pCvt, xFont_ ); |
|
|
885 |
} |
915 |
} |
886 |
|
916 |
|
887 |
void |
917 |
void |
888 |
SalGraphics::DrawText( long nX, long nY, const xub_Unicode* pStr, USHORT nLen ) |
918 |
SalGraphics::DrawText (long nX, long nY, const xub_Unicode * pStr, |
889 |
{ |
919 |
USHORT nLen) |
890 |
maGraphicsData.DrawText( nX, nY, pStr, nLen ); |
920 |
{ |
|
|
921 |
maGraphicsData.DrawText (nX, nY, pStr, nLen); |
891 |
} |
922 |
} |
892 |
|
923 |
|
893 |
//-------------------------------------------------------------------------- |
924 |
//-------------------------------------------------------------------------- |
894 |
|
925 |
|
895 |
static BOOL |
926 |
static BOOL |
896 |
CheckNoNegativeCoordinateWorkaround() |
927 |
CheckNoNegativeCoordinateWorkaround () |
897 |
{ |
928 |
{ |
898 |
/* Motivation: one of our clients uses a Solaris 2.4 X86 system with an |
929 |
/* Motivation: one of our clients uses a Solaris 2.4 X86 system with an |
899 |
XServer for the Matrox Mystique graphics card. This board/server |
930 |
XServer for the Matrox Mystique graphics card. This board/server |
900 |
sometimes does not draw Text with negative x-coordinates into a |
931 |
sometimes does not draw Text with negative x-coordinates into a |
901 |
virtual device (for unknown reasons). A stock X-server just clips the |
932 |
virtual device (for unknown reasons). A stock X-server just clips the |
902 |
part in the negative area. */ |
933 |
part in the negative area. */ |
903 |
static int nCheck = -2; |
934 |
static int nCheck = -2; |
904 |
if( nCheck == -2 ) |
935 |
if (nCheck == -2) |
905 |
{ |
936 |
{ |
906 |
char* pCmp = getenv( "SAL_NO_NEGATIVE_TEXT_OFFSET" ); |
937 |
char *pCmp = getenv ("SAL_NO_NEGATIVE_TEXT_OFFSET"); |
907 |
if( pCmp && ! strncasecmp( pCmp, "true", 4 ) ) |
938 |
if (pCmp && !strncasecmp (pCmp, "true", 4)) |
908 |
nCheck = 1; |
939 |
nCheck = 1; |
909 |
else |
940 |
else |
910 |
nCheck = 0; |
941 |
nCheck = 0; |
911 |
} |
942 |
} |
912 |
return nCheck ? TRUE : FALSE; |
943 |
return nCheck ? TRUE : FALSE; |
913 |
} |
944 |
} |
914 |
|
|
|
915 |
void |
916 |
SalGraphicsData::DrawText( |
917 |
long nX, long nY, |
918 |
const sal_Unicode* pStr, USHORT nLen, const long* pDXAry ) |
919 |
{ |
920 |
#ifndef PRINTER_DUMMY |
921 |
if( bPrinter_ ) |
922 |
FaxPhoneComment( GetXDisplay(), pStr, nLen ); |
923 |
#endif |
924 |
GC pGC = SelectFont(); |
925 |
|
926 |
// workaround for problems with negative coordinates |
927 |
long* pTmpAry = NULL; |
928 |
if( nX < 0 && CheckNoNegativeCoordinateWorkaround() ) |
929 |
{ |
930 |
long nOldX = nX; |
931 |
while( nX < 0 ) |
932 |
{ |
933 |
nX = nOldX + *pDXAry; |
934 |
pStr++, pDXAry++, nLen--; |
935 |
if( nLen < 1 ) |
936 |
return; |
937 |
} |
938 |
pTmpAry = new long[ nLen ]; |
939 |
for( int q = 0; q < nLen-1; q++ ) |
940 |
pTmpAry[q] = pDXAry[q] - ( nX - nOldX ); |
941 |
pDXAry = pTmpAry; |
942 |
} |
943 |
|
944 |
// draw every single character |
945 |
SalConverterCache *pCvt = GetDisplay()->GetConverter(); |
946 |
int angle = nFontOrientation_ * 64 / 10; |
947 |
BOOL bVertical = bFontVertical_; |
948 |
Polygon aPolygon(1); |
949 |
Point aOrigin( nX, nY ); |
950 |
Point aCharPos; |
951 |
|
952 |
DrawString( GetXDisplay(), hDrawable_, pGC, |
953 |
aOrigin.X(), aOrigin.Y(), pStr, 1, angle, bVertical, pCvt, xFont_ ); |
954 |
|
945 |
|
955 |
for( int i = 1; i < nLen ; i++ ) |
946 |
void |
956 |
{ |
947 |
SalGraphicsData::DrawText (long nX, long nY, |
957 |
aCharPos = Point( aOrigin.X() + pDXAry[ i - 1 ], aOrigin.Y() ); |
948 |
const sal_Unicode * pStr, USHORT nLen, |
958 |
aPolygon.SetPoint( aCharPos, 0 ); |
949 |
const long *pDXAry) |
959 |
aPolygon.Rotate( aOrigin, nFontOrientation_ ); |
950 |
{ |
960 |
aCharPos = aPolygon.GetPoint( 0 ); |
951 |
#ifndef PRINTER_DUMMY |
|
|
952 |
if (bPrinter_) |
953 |
FaxPhoneComment (GetXDisplay (), pStr, nLen); |
954 |
#endif |
955 |
GC pGC = SelectFont (); |
961 |
|
956 |
|
962 |
DrawString( GetXDisplay(), hDrawable_, pGC, |
957 |
// workaround for problems with negative coordinates |
963 |
aCharPos.X(), aCharPos.Y(), pStr + i, 1, angle, bVertical, pCvt, xFont_ ); |
958 |
long *pTmpAry = NULL; |
964 |
} |
959 |
if (nX < 0 && CheckNoNegativeCoordinateWorkaround ()) |
|
|
960 |
{ |
961 |
long nOldX = nX; |
962 |
while (nX < 0) |
963 |
{ |
964 |
nX = nOldX + *pDXAry; |
965 |
pStr++, pDXAry++, nLen--; |
966 |
if (nLen < 1) |
967 |
return; |
968 |
} |
969 |
pTmpAry = new long[nLen]; |
970 |
for (int q = 0; q < nLen - 1; q++) |
971 |
pTmpAry[q] = pDXAry[q] - (nX - nOldX); |
972 |
pDXAry = pTmpAry; |
973 |
} |
974 |
|
975 |
// draw every single character |
976 |
SalConverterCache *pCvt = GetDisplay ()->GetConverter (); |
977 |
int angle = nFontOrientation_ * 64 / 10; |
978 |
BOOL bVertical = bFontVertical_; |
979 |
Polygon aPolygon (1); |
980 |
Point aOrigin (nX, nY); |
981 |
Point aCharPos; |
982 |
|
983 |
DrawString (GetXDisplay (), hDrawable_, pGC, |
984 |
aOrigin.X (), aOrigin.Y (), pStr, 1, angle, bVertical, pCvt, |
985 |
xFont_); |
986 |
|
987 |
for (int i = 1; i < nLen; i++) |
988 |
{ |
989 |
aCharPos = Point (aOrigin.X () + pDXAry[i - 1], aOrigin.Y ()); |
990 |
aPolygon.SetPoint (aCharPos, 0); |
991 |
aPolygon.Rotate (aOrigin, nFontOrientation_); |
992 |
aCharPos = aPolygon.GetPoint (0); |
993 |
|
994 |
DrawString (GetXDisplay (), hDrawable_, pGC, |
995 |
aCharPos.X (), aCharPos.Y (), pStr + i, 1, angle, bVertical, |
996 |
pCvt, xFont_); |
997 |
} |
965 |
|
998 |
|
966 |
if( pTmpAry ) |
999 |
if (pTmpAry) |
967 |
delete pTmpAry; |
1000 |
delete pTmpAry; |
968 |
} |
1001 |
} |
969 |
|
1002 |
|
970 |
// ---------------------------------------------------------------------------- |
1003 |
// ---------------------------------------------------------------------------- |
Lines 973-1184
Link Here
|
973 |
// |
1006 |
// |
974 |
// ---------------------------------------------------------------------------- |
1007 |
// ---------------------------------------------------------------------------- |
975 |
|
1008 |
|
976 |
USHORT |
1009 |
USHORT SalGraphics::SetFont (ImplFontSelectData * pEntry) |
977 |
SalGraphics::SetFont( ImplFontSelectData *pEntry ) |
1010 |
{ |
978 |
{ |
1011 |
maGraphicsData.SetFont (pEntry); |
979 |
maGraphicsData.SetFont( pEntry ); |
1012 |
return _IsPrinter ()? SAL_SETFONT_USEDRAWTEXTARRAY : 0; |
980 |
return _IsPrinter() ? SAL_SETFONT_USEDRAWTEXTARRAY : 0; |
|
|
981 |
} |
1013 |
} |
982 |
|
1014 |
|
983 |
// ---------------------------------------------------------------------------- |
1015 |
// ---------------------------------------------------------------------------- |
984 |
|
1016 |
|
985 |
void |
1017 |
void |
986 |
SalGraphics::DrawTextArray( long nX, long nY, |
1018 |
SalGraphics::DrawTextArray (long nX, long nY, |
987 |
const xub_Unicode *pStr, USHORT nLen, const long *pDXAry ) |
1019 |
const xub_Unicode * pStr, USHORT nLen, |
988 |
{ |
1020 |
const long *pDXAry) |
989 |
maGraphicsData.DrawText( nX, nY, pStr, nLen, pDXAry ); |
1021 |
{ |
|
|
1022 |
maGraphicsData.DrawText (nX, nY, pStr, nLen, pDXAry); |
990 |
} |
1023 |
} |
991 |
|
1024 |
|
992 |
// ---------------------------------------------------------------------------- |
1025 |
// ---------------------------------------------------------------------------- |
993 |
|
1026 |
|
994 |
void |
1027 |
void |
995 |
SalGraphics::SetTextColor( SalColor nSalColor ) |
1028 |
SalGraphics::SetTextColor (SalColor nSalColor) |
996 |
{ |
1029 |
{ |
997 |
if( _GetTextColor() != nSalColor ) |
1030 |
if (_GetTextColor () != nSalColor) |
998 |
{ |
1031 |
{ |
999 |
_GetTextColor() = nSalColor; |
1032 |
_GetTextColor () = nSalColor; |
1000 |
_GetTextPixel() = _GetPixel( nSalColor ); |
1033 |
_GetTextPixel () = _GetPixel (nSalColor); |
1001 |
_IsFontGC() = FALSE; |
1034 |
_IsFontGC () = FALSE; |
1002 |
} |
1035 |
} |
1003 |
} |
1036 |
} |
1004 |
|
1037 |
|
1005 |
// ---------------------------------------------------------------------------- |
1038 |
// ---------------------------------------------------------------------------- |
1006 |
|
1039 |
|
1007 |
void |
1040 |
void |
1008 |
SalGraphics::GetDevFontList( ImplDevFontList *pList ) |
1041 |
SalGraphics::GetDevFontList (ImplDevFontList * pList) |
1009 |
{ |
1042 |
{ |
1010 |
XlfdStorage* pFonts = _GetDisplay()->GetXlfdList(); |
1043 |
XlfdStorage *pFonts = _GetDisplay ()->GetXlfdList (); |
1011 |
|
1044 |
|
1012 |
for ( int nIdx = 0; nIdx < pFonts->GetCount(); nIdx++ ) |
1045 |
for (int nIdx = 0; nIdx < pFonts->GetCount (); nIdx++) |
1013 |
{ |
1046 |
{ |
1014 |
ImplFontData *pFontData = new ImplFontData; |
1047 |
ImplFontData *pFontData = new ImplFontData; |
1015 |
pFonts->Get(nIdx)->ToImplFontData( pFontData ); |
1048 |
pFonts->Get (nIdx)->ToImplFontData (pFontData); |
1016 |
pList->Add( pFontData ); |
1049 |
pList->Add (pFontData); |
1017 |
} |
1050 |
} |
1018 |
} |
1051 |
} |
1019 |
|
1052 |
|
1020 |
// ---------------------------------------------------------------------------- |
1053 |
// ---------------------------------------------------------------------------- |
1021 |
|
1054 |
|
1022 |
inline long |
1055 |
inline long |
1023 |
sal_DivideNeg( long n1, long n2 ) |
1056 |
sal_DivideNeg (long n1, long n2) |
1024 |
{ |
1057 |
{ |
1025 |
return ( n1 < 0 ) ? (n1 - n2 / 2) / n2 : (n1 + n2 / 2) / n2; |
1058 |
return (n1 < 0) ? (n1 - n2 / 2) / n2 : (n1 + n2 / 2) / n2; |
1026 |
} |
1059 |
} |
1027 |
|
1060 |
|
1028 |
void |
1061 |
void |
1029 |
SalGraphics::GetFontMetric( ImplFontMetricData *pMetric ) |
1062 |
SalGraphics::GetFontMetric (ImplFontMetricData * pMetric) |
1030 |
{ |
1063 |
{ |
1031 |
ExtendedFontStruct* pFont = maGraphicsData.xFont_; |
1064 |
ExtendedFontStruct *pFont = maGraphicsData.xFont_; |
1032 |
|
1065 |
|
1033 |
if ( pFont != NULL ) |
1066 |
if (pFont != NULL) |
1034 |
{ |
1067 |
{ |
1035 |
pFont->ToImplFontMetricData( pMetric ); |
1068 |
pFont->ToImplFontMetricData (pMetric); |
1036 |
|
1069 |
|
1037 |
if( XSalCanDrawRotString( maGraphicsData.GetXDisplay(), None ) ) |
1070 |
if (XSalCanDrawRotString (maGraphicsData.GetXDisplay (), None)) |
1038 |
pMetric->mnOrientation = maGraphicsData.nFontOrientation_; |
1071 |
pMetric->mnOrientation = maGraphicsData.nFontOrientation_; |
1039 |
if ( maGraphicsData.bFontVertical_ ) |
1072 |
if (maGraphicsData.bFontVertical_) |
1040 |
pMetric->mnOrientation = 2700; |
1073 |
pMetric->mnOrientation = 2700; |
1041 |
|
1074 |
|
1042 |
long n; |
1075 |
long n; |
1043 |
|
1076 |
|
1044 |
n = maGraphicsData.aScale_.GetNumerator(); |
1077 |
n = maGraphicsData.aScale_.GetNumerator (); |
1045 |
if( n != 1 ) |
1078 |
if (n != 1) |
1046 |
{ |
1079 |
{ |
1047 |
pMetric->mnWidth *= n; |
1080 |
pMetric->mnWidth *= n; |
1048 |
pMetric->mnAscent *= n; |
1081 |
pMetric->mnAscent *= n; |
1049 |
pMetric->mnDescent *= n; |
1082 |
pMetric->mnDescent *= n; |
1050 |
pMetric->mnLeading *= n; |
1083 |
pMetric->mnLeading *= n; |
1051 |
pMetric->mnSlant *= n; |
1084 |
pMetric->mnSlant *= n; |
1052 |
} |
|
|
1053 |
|
1054 |
n = maGraphicsData.aScale_.GetDenominator(); |
1055 |
if( n != 1 ) |
1056 |
{ |
1057 |
pMetric->mnWidth = Divide( pMetric->mnWidth, n ); |
1058 |
pMetric->mnAscent = sal_DivideNeg( pMetric->mnAscent, n ); |
1059 |
pMetric->mnDescent = sal_DivideNeg( pMetric->mnDescent, n ); |
1060 |
pMetric->mnLeading = sal_DivideNeg( pMetric->mnLeading, n ); |
1061 |
pMetric->mnSlant = sal_DivideNeg( pMetric->mnSlant, n ); |
1062 |
} |
1063 |
} |
1085 |
} |
|
|
1086 |
|
1087 |
n = maGraphicsData.aScale_.GetDenominator (); |
1088 |
if (n != 1) |
1089 |
{ |
1090 |
pMetric->mnWidth = Divide (pMetric->mnWidth, n); |
1091 |
pMetric->mnAscent = sal_DivideNeg (pMetric->mnAscent, n); |
1092 |
pMetric->mnDescent = sal_DivideNeg (pMetric->mnDescent, n); |
1093 |
pMetric->mnLeading = sal_DivideNeg (pMetric->mnLeading, n); |
1094 |
pMetric->mnSlant = sal_DivideNeg (pMetric->mnSlant, n); |
1095 |
} |
1096 |
} |
1064 |
} |
1097 |
} |
1065 |
|
1098 |
|
1066 |
// --------------------------------------------------------------------------- |
1099 |
// --------------------------------------------------------------------------- |
1067 |
|
1100 |
|
1068 |
static long |
1101 |
static long |
1069 |
InitializeWidthArray( long *pWidthArray, sal_Size nItems, int nValue = 0 ) |
1102 |
InitializeWidthArray (long *pWidthArray, sal_Size nItems, int nValue = 0) |
1070 |
{ |
1103 |
{ |
1071 |
const long nPrecision = 1; |
1104 |
const long nPrecision = 1; |
1072 |
|
1105 |
|
1073 |
for ( int i = 0; i < nItems; i++, pWidthArray++ ) |
1106 |
for (int i = 0; i < nItems; i++, pWidthArray++) |
1074 |
*pWidthArray = nValue; |
1107 |
*pWidthArray = nValue; |
1075 |
|
1108 |
|
1076 |
return nPrecision; |
1109 |
return nPrecision; |
1077 |
} |
1110 |
} |
1078 |
|
1111 |
|
1079 |
long |
1112 |
long |
1080 |
SalGraphics::GetCharWidth( USHORT nChar1, USHORT nChar2, long *pWidthAry ) |
1113 |
SalGraphics::GetCharWidth (USHORT nChar1, USHORT nChar2, long *pWidthAry) |
1081 |
{ |
1114 |
{ |
1082 |
// return the precision of the calculated charwidth, e.g. 1000 = 3 digits |
1115 |
// return the precision of the calculated charwidth, e.g. 1000 = 3 digits |
1083 |
// defaultet to 1 for now |
1116 |
// defaultet to 1 for now |
1084 |
const long nPrecision = 1; |
1117 |
const long nPrecision = 1; |
1085 |
int nRequestedWidth = nChar2 - nChar1 + 1; |
1118 |
int nRequestedWidth = nChar2 - nChar1 + 1; |
1086 |
int nCharWidth; |
1119 |
int nCharWidth; |
1087 |
|
1120 |
|
1088 |
// XXX sanity check, this may happen if no font at all is installed |
1121 |
// XXX sanity check, this may happen if no font at all is installed |
1089 |
// or no system font matches the requirements for the user interface |
1122 |
// or no system font matches the requirements for the user interface |
1090 |
if ( maGraphicsData.xFont_ == NULL ) |
1123 |
if (maGraphicsData.xFont_ == NULL) |
1091 |
return InitializeWidthArray( pWidthAry, nRequestedWidth, 12 ); |
1124 |
return InitializeWidthArray (pWidthAry, nRequestedWidth, 12); |
1092 |
|
1125 |
|
1093 |
// the font should know it's metrics best |
1126 |
// the font should know it's metrics best |
1094 |
SalDisplay *pSalDisplay = maGraphicsData.GetDisplay(); |
1127 |
SalDisplay *pSalDisplay = maGraphicsData.GetDisplay (); |
1095 |
|
1128 |
|
1096 |
nCharWidth = maGraphicsData.xFont_->GetCharWidth( |
1129 |
nCharWidth = |
1097 |
pSalDisplay->GetConverter(), nChar1, nChar2, pWidthAry ); |
1130 |
maGraphicsData.xFont_->GetCharWidth (pSalDisplay->GetConverter (), nChar1, |
1098 |
|
1131 |
nChar2, pWidthAry); |
1099 |
// XXX sanity check, this may happen if the font cannot be loaded/queried |
1132 |
|
1100 |
// either because of a garbled fontpath or because of invalid fontfile |
1133 |
// XXX sanity check, this may happen if the font cannot be loaded/queried |
1101 |
if ( nCharWidth != nRequestedWidth ) |
1134 |
// either because of a garbled fontpath or because of invalid fontfile |
1102 |
InitializeWidthArray( pWidthAry + nCharWidth, |
1135 |
if (nCharWidth != nRequestedWidth) |
1103 |
nRequestedWidth - nCharWidth ); |
1136 |
InitializeWidthArray (pWidthAry + nCharWidth, |
1104 |
|
1137 |
nRequestedWidth - nCharWidth); |
1105 |
// handle internal scaling |
1138 |
|
1106 |
const long nNumerator = maGraphicsData.aScale_.GetNumerator(); |
1139 |
// handle internal scaling |
1107 |
const long nDenominator = maGraphicsData.aScale_.GetDenominator(); |
1140 |
const long nNumerator = maGraphicsData.aScale_.GetNumerator (); |
1108 |
long *pPtr; |
1141 |
const long nDenominator = maGraphicsData.aScale_.GetDenominator (); |
1109 |
sal_Unicode nChar; |
1142 |
long *pPtr; |
1110 |
|
1143 |
sal_Unicode nChar; |
1111 |
if ( nNumerator != 1 ) |
1144 |
|
1112 |
for( pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) |
1145 |
if (nNumerator != 1) |
1113 |
*pPtr *= nNumerator; |
1146 |
for (pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) |
1114 |
if ( nDenominator != 1 ) |
1147 |
*pPtr *= nNumerator; |
1115 |
for( pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) |
1148 |
if (nDenominator != 1) |
1116 |
*pPtr = Divide( *pPtr, nDenominator ); |
1149 |
for (pPtr = pWidthAry, nChar = nChar1; nChar <= nChar2; nChar++, pPtr++) |
|
|
1150 |
*pPtr = Divide (*pPtr, nDenominator); |
1117 |
|
1151 |
|
1118 |
// return |
1152 |
// return |
1119 |
return nPrecision; |
1153 |
return nPrecision; |
1120 |
} |
1154 |
} |
1121 |
|
1155 |
|
1122 |
// --------------------------------------------------------------------------- |
1156 |
// --------------------------------------------------------------------------- |
1123 |
|
1157 |
|
1124 |
extern unsigned char TranslateCharName( char* ); |
1158 |
extern unsigned char TranslateCharName (char *); |
1125 |
|
1159 |
|
1126 |
ULONG |
1160 |
ULONG SalGraphics::GetKernPairs (ULONG nPairs, ImplKernPairData * pKernPairs) |
1127 |
SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData *pKernPairs ) |
|
|
1128 |
{ |
1161 |
{ |
1129 |
if( ! _IsPrinter() ) |
1162 |
if (!_IsPrinter ()) |
1130 |
return 0; |
1163 |
return 0; |
1131 |
|
1164 |
|
1132 |
// get pair kerning table ( internal data from xprinter ) |
1165 |
// get pair kerning table ( internal data from xprinter ) |
1133 |
int i, nCurPair=0; |
1166 |
int |
1134 |
|
1167 |
i, nCurPair = 0; |
1135 |
// XXX Fix me, improve this to be multi encoding aware: merge kern |
1168 |
|
1136 |
// pair list for all encodings available in the xfont |
1169 |
// XXX Fix me, improve this to be multi encoding aware: merge kern |
1137 |
rtl_TextEncoding nEncoding = maGraphicsData.xFont_->GetAsciiEncoding(); |
1170 |
// pair list for all encodings available in the xfont |
1138 |
XFontStruct *pXFS = maGraphicsData.xFont_->GetFontStruct( nEncoding ); |
1171 |
rtl_TextEncoding |
1139 |
XExtData *pXES = pXFS->ext_data; |
1172 |
nEncoding = maGraphicsData.xFont_->GetAsciiEncoding (); |
1140 |
|
1173 |
XFontStruct * |
1141 |
for( i = 0; pXES && i < 2; i++, pXES = pXES->next ); |
1174 |
pXFS = maGraphicsData.xFont_->GetFontStruct (nEncoding); |
1142 |
if( i < 2 ) |
1175 |
XExtData * |
1143 |
return 0; |
1176 |
pXES = pXFS->ext_data; |
1144 |
XpPairKernData* pXpPKD = (XpPairKernData*)(pXES->private_data); |
1177 |
|
1145 |
PairKernData* pPKD = pXpPKD->pkd; |
1178 |
for (i = 0; pXES && i < 2; i++, pXES = pXES->next); |
1146 |
|
1179 |
if (i < 2) |
1147 |
for( i = 0, nCurPair=0; i < pXpPKD->numOfPairs; i++ ) |
1180 |
return 0; |
1148 |
{ |
1181 |
XpPairKernData * |
1149 |
unsigned char c1 = TranslateCharName( pPKD[i].name1 ); |
1182 |
pXpPKD = (XpPairKernData *) (pXES->private_data); |
1150 |
unsigned char c2 = TranslateCharName( pPKD[i].name2 ); |
1183 |
PairKernData * |
1151 |
if( c1 && c2 ) |
1184 |
pPKD = pXpPKD->pkd; |
1152 |
{ |
1185 |
|
1153 |
if( pKernPairs && nCurPair < nPairs ) |
1186 |
for (i = 0, nCurPair = 0; i < pXpPKD->numOfPairs; i++) |
1154 |
{ |
1187 |
{ |
1155 |
pKernPairs[ nCurPair ].mnChar1 = c1; |
1188 |
unsigned char |
1156 |
pKernPairs[ nCurPair ].mnChar2 = c2; |
1189 |
c1 = TranslateCharName (pPKD[i].name1); |
1157 |
pKernPairs[ nCurPair ].mnKern = |
1190 |
unsigned char |
1158 |
(long)(pPKD[i].xamt * pXpPKD->pointsize / 1000 ); |
1191 |
c2 = TranslateCharName (pPKD[i].name2); |
1159 |
} |
1192 |
if (c1 && c2) |
1160 |
nCurPair++; |
1193 |
{ |
1161 |
} |
1194 |
if (pKernPairs && nCurPair < nPairs) |
|
|
1195 |
{ |
1196 |
pKernPairs[nCurPair].mnChar1 = c1; |
1197 |
pKernPairs[nCurPair].mnChar2 = c2; |
1198 |
pKernPairs[nCurPair].mnKern = |
1199 |
(long) (pPKD[i].xamt * pXpPKD->pointsize / 1000); |
1200 |
} |
1201 |
nCurPair++; |
1162 |
} |
1202 |
} |
|
|
1203 |
} |
1163 |
|
1204 |
|
1164 |
return nCurPair; |
1205 |
return nCurPair; |
1165 |
} |
1206 |
} |
1166 |
|
1207 |
|
1167 |
// --------------------------------------------------------------------------- |
1208 |
// --------------------------------------------------------------------------- |
1168 |
|
1209 |
|
1169 |
BOOL |
1210 |
BOOL |
1170 |
SalGraphics::GetGlyphBoundRect( xub_Unicode c, |
1211 |
SalGraphics::GetGlyphBoundRect (xub_Unicode c, |
1171 |
long *pX, long *pY, long *pDX, long *pDY ) |
1212 |
long *pX, long *pY, long *pDX, long *pDY) |
1172 |
{ |
1213 |
{ |
1173 |
return FALSE; |
1214 |
return FALSE; |
1174 |
} |
1215 |
} |
1175 |
|
1216 |
|
1176 |
// --------------------------------------------------------------------------- |
1217 |
// --------------------------------------------------------------------------- |
1177 |
|
1218 |
|
1178 |
ULONG |
1219 |
ULONG |
1179 |
SalGraphics::GetGlyphOutline( xub_Unicode c, |
1220 |
SalGraphics::GetGlyphOutline (xub_Unicode c, |
1180 |
USHORT **ppPolySizes, SalPoint **ppPoints, BYTE **ppFlags ) |
1221 |
USHORT ** ppPolySizes, SalPoint ** ppPoints, |
|
|
1222 |
BYTE ** ppFlags) |
1181 |
{ |
1223 |
{ |
1182 |
return 0; |
1224 |
return 0; |
1183 |
} |
1225 |
} |
1184 |
|
|
|