View | Details | Raw Unified | Return to issue 345
Collapse All | Expand All

(-)salgdi3.cxx (-870 / +911 lines)
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

Return to issue 345