00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104 #include "textfuns.h"
00105
00106
00107 #include "camelot.h"
00108 #include "fontman.h"
00109 #ifndef EXCLUDE_FROM_XARALX
00110 #include "atmfonts.h"
00111 #endif
00112 #include "unicdman.h"
00113
00114 DECLARE_SOURCE( "$Revision: 1495 $" );
00115
00116 CC_IMPLEMENT_MEMDUMP( CharMetrics, CC_CLASS_MEMDUMP );
00117
00118 #define new CAM_DEBUG_NEW
00119
00120
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 CharMetrics::CharMetrics()
00133 {
00134 CharWidth = 0;
00135 FontAscent = 0;
00136 FontDescent = 0;
00137 FontEmWidth = 0;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void CharMetrics::Scale(double ScaleX, double ScaleY)
00152 {
00153 CharWidth = (MILLIPOINT)(CharWidth * ScaleX + 0.5);
00154 FontEmWidth = (MILLIPOINT)(FontEmWidth * ScaleX + 0.5);
00155 FontAscent = (MILLIPOINT)(FontAscent * ScaleY + 0.5);
00156 FontDescent = (MILLIPOINT)(FontDescent * ScaleY + 0.5);
00157 }
00158
00159
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 BOOL TextManager::GetTTCharPath(CharDescription& ChDesc, DocCoord** ppCoords,
00180 PathVerb** ppVerbs, UINT32* pNumCoords, wxDC* pDC)
00181 {
00182 PORTNOTE("text", "no TrueType font manager in wxOil")
00183 #ifndef EXCLUDE_FROM_XARALX
00184 ERROR2IF(ppCoords==NULL,FALSE,"TextManager::GetTTCharPath pCoords==NULL");
00185 ERROR2IF(ppVerbs==NULL,FALSE,"TextManager::GetTTCharPath ppVerbs==NULL");
00186 ERROR2IF(pNumCoords==NULL,FALSE,"TextManager::GetTTCharPath pNumCoords==NULL");
00187
00188 const CharPathBufferSize=2048;
00189 static DocCoord CharPathCoordArray[CharPathBufferSize];
00190 static PathVerb CharPathVerbArray[CharPathBufferSize];
00191
00192
00193 BOOL LocalDC=(pDC==NULL);
00194 if (LocalDC)
00195 {
00196 pDC=new CDC;
00197 if (pDC==NULL)
00198 {
00199 ERROR3("TextManager::GetCharPath() - failed to create DC");
00200 return FALSE;
00201 }
00202 if (pDC->CreateCompatibleDC(NULL)==FALSE)
00203 {
00204 delete pDC;
00205 ERROR3("TextManager::GetCharPath() - CreateCompatibleDC() failed");
00206 return FALSE;
00207 }
00208 }
00209
00210
00211 LOGFONT CharLogFont;
00212 BOOL ok=GetLogFontFromCharDescriptor(pDC, ChDesc, &CharLogFont);
00213 UINT32 Coords=CharPathBufferSize;
00214 if (ok)
00215 {
00216 ok=GetBezierFromChar(pDC, ChDesc.GetCharCode(), &CharLogFont, &Coords, (POINT*)CharPathCoordArray, CharPathVerbArray);
00217
00218
00219 if (!ok)
00220 {
00221
00222 WCHAR DefChar = (unsigned char)'?';
00223 TEXTMETRIC FontTextData;
00224 #ifdef _UNCCODE
00225 if (pDC->GetTextMetrics(&FontTextData))
00226 DefChar = FontTextData.tmDefaultChar;
00227 #else
00228 if (pDC->GetTextMetrics(&FontTextData))
00229 DefChar = (unsigned char)FontTextData.tmDefaultChar;
00230 #endif
00231
00232 ok = GetBezierFromChar(pDC, DefChar, &CharLogFont, &Coords, (POINT*)CharPathCoordArray, CharPathVerbArray);
00233 }
00234
00235 ERROR3IF(!ok, "TextManager::GetCharPath error from GetBezierFromChar");
00236 }
00237
00238
00239 if (ok)
00240 {
00241 *ppCoords = CharPathCoordArray;
00242 *ppVerbs = CharPathVerbArray;
00243 *pNumCoords = Coords;
00244 }
00245 if (LocalDC) delete pDC;
00246 return ok;
00247 #else
00248 return FALSE;
00249 #endif
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 #define FIXEDTOINT32(FIXED) (*((INT32 *)&FIXED))
00276 #define SCALEX(jobby) (MulDiv(MulDiv(jobby,72000,DivConstX),pLogFont->lfHeight,-4096))
00277 #define SCALEY(jobby) (MulDiv(MulDiv(jobby,72000,DivConstY),pLogFont->lfHeight,-4096))
00278
00279 BOOL TextManager::GetBezierFromChar(wxDC* pDC,WCHAR CharNumber,
00280 LPLOGFONT pLogFont, DWORD* NoPolyElements, POINT* pPolyCordBuffer, BYTE* pPolyVerbBuffer)
00281 {
00282 PORTNOTE("text", "no TrueType font manager in wxOil")
00283 #ifndef EXCLUDE_FROM_XARALX
00284 if (*NoPolyElements==0)
00285 {
00286 *NoPolyElements=2000;
00287 return TRUE;
00288 }
00289
00290 INT32 DivConstX=pDC->GetDeviceCaps(LOGPIXELSX)<<16;
00291 INT32 DivConstY=pDC->GetDeviceCaps(LOGPIXELSY)<<16;
00292
00293 LOGFONT TempLogFont=*pLogFont;
00294 TempLogFont.lfHeight=-4096;
00295 TempLogFont.lfWidth=0;
00296 CFont UnHintedCFont;
00297 UnHintedCFont.CreateFontIndirect(&TempLogFont);
00298 CFont* pOldCFont=pDC->SelectObject(&UnHintedCFont);
00299
00300 MAT2 DefaultMatrix={ {0,1} ,{0,0}, {0,0}, {0,1} };
00301 TEXTMETRIC ATextMetricStruct;
00302 pDC->GetTextMetrics(&ATextMetricStruct);
00303 GLYPHMETRICS GlyphMetricsBuffer;
00304
00305
00306 DWORD SizeOfGlyphData = (DWORD)-1;
00307 UINT32 MBChar = 0;
00308 if (UnicodeManager::IsUnicodeCompleteOS())
00309 SizeOfGlyphData = GetGlyphOutlineW(pDC->GetSafeHdc(), CharNumber, GGO_NATIVE, &GlyphMetricsBuffer, 0, NULL, &DefaultMatrix);
00310 else
00311 {
00312 MBChar = UnicodeManager::UnicodeToMultiByte(CharNumber);
00313 SizeOfGlyphData = GetGlyphOutlineA(pDC->GetSafeHdc(), MBChar, GGO_NATIVE, &GlyphMetricsBuffer, 0, NULL, &DefaultMatrix);
00314 }
00315 if (SizeOfGlyphData==-1)
00316 return FALSE;
00317
00318
00319 BYTE* pGlyphBuffer= new BYTE[SizeOfGlyphData];
00320 if (pGlyphBuffer == NULL)
00321 return FALSE;
00322
00323
00324 DWORD Error = (DWORD)-1;
00325 if (UnicodeManager::IsUnicodeCompleteOS())
00326 Error = GetGlyphOutlineW(pDC->GetSafeHdc(), CharNumber, GGO_NATIVE, &GlyphMetricsBuffer, SizeOfGlyphData, pGlyphBuffer, &DefaultMatrix);
00327 else
00328 Error = GetGlyphOutlineA(pDC->GetSafeHdc(), MBChar, GGO_NATIVE, &GlyphMetricsBuffer, SizeOfGlyphData, pGlyphBuffer, &DefaultMatrix);
00329
00330 if (Error == -1)
00331 {
00332 delete[] pGlyphBuffer;
00333 ERROR2(FALSE, "GetGlyphOutline failed");
00334 }
00335
00336
00337 pDC->SelectObject(pOldCFont);
00338
00339
00340
00341
00342 BYTE* pPosInGlyphBuffer=(BYTE*)pGlyphBuffer;
00343 DWORD ContourSize;
00344 TTPOLYGONHEADER* pPolyHeader;
00345 TTPOLYCURVE* pPolyCurve;
00346 DWORD CurrentPolyIndex=0;
00347 WORD NoOfArrayElements;
00348 INT32 CurrentX;
00349 INT32 CurrentY;
00350 DWORD FirstContourIndex;
00351
00352 while (pPosInGlyphBuffer<(BYTE*)pGlyphBuffer+SizeOfGlyphData)
00353 {
00354
00355 pPolyHeader=(TTPOLYGONHEADER*)pPosInGlyphBuffer;
00356 ContourSize=pPolyHeader->cb;
00357 CurrentX=FIXEDTOINT32(pPolyHeader->pfxStart.x);
00358 CurrentY=FIXEDTOINT32(pPolyHeader->pfxStart.y);
00359 pPolyCordBuffer[CurrentPolyIndex].x=SCALEX(CurrentX);
00360 pPolyCordBuffer[CurrentPolyIndex].y=SCALEY(CurrentY);
00361 pPolyVerbBuffer[CurrentPolyIndex] =PT_MOVETO;
00362 FirstContourIndex=CurrentPolyIndex;
00363 CurrentPolyIndex++;
00364
00365 pPosInGlyphBuffer=pPosInGlyphBuffer+sizeof(TTPOLYGONHEADER);
00366
00367
00368 do
00369 {
00370 if (CurrentPolyIndex+4>=*NoPolyElements)
00371 {
00372 delete[] pGlyphBuffer;
00373 TRACE( _T("overflowing polydraw buffer"));
00374 return FALSE;
00375 }
00376
00377 pPolyCurve=(TTPOLYCURVE*)pPosInGlyphBuffer;
00378 NoOfArrayElements=pPolyCurve->cpfx;
00379
00380 DWORD i;
00381 switch (pPolyCurve->wType)
00382 {
00383 case TT_PRIM_LINE:
00384 for (i=0;i<NoOfArrayElements;i++)
00385 {
00386 CurrentX=FIXEDTOINT32(pPolyCurve->apfx[i].x);
00387 pPolyCordBuffer[CurrentPolyIndex].x=SCALEX(CurrentX);
00388 CurrentY=FIXEDTOINT32(pPolyCurve->apfx[i].y);
00389 pPolyCordBuffer[CurrentPolyIndex].y=SCALEY(CurrentY);
00390 pPolyVerbBuffer[CurrentPolyIndex]=PT_LINETO;
00391 CurrentPolyIndex++;
00392 }
00393 break;
00394
00395
00396 case TT_PRIM_QSPLINE:
00397
00398 for ( i=0;i+1<NoOfArrayElements;i++)
00399 {
00400 pPolyVerbBuffer[CurrentPolyIndex]=PT_BEZIERTO;
00401 pPolyVerbBuffer[CurrentPolyIndex+1]=PT_BEZIERTO;
00402 pPolyVerbBuffer[CurrentPolyIndex+2]=PT_BEZIERTO;
00403
00404
00405
00406 pPolyCordBuffer[CurrentPolyIndex].x=
00407
00408
00409 SCALEX(CurrentX/3) + SCALEX(((FIXEDTOINT32(pPolyCurve->apfx[i].x))<<1)/3);
00410
00411 pPolyCordBuffer[CurrentPolyIndex].y=
00412
00413
00414 SCALEY(CurrentY/3) + SCALEY(((FIXEDTOINT32(pPolyCurve->apfx[i].y))<<1)/3);
00415
00416 if (i+2==NoOfArrayElements)
00417 {
00418 CurrentX=FIXEDTOINT32(pPolyCurve->apfx[i+1].x);
00419 pPolyCordBuffer[CurrentPolyIndex+2].x=SCALEX(CurrentX);
00420 CurrentY=FIXEDTOINT32(pPolyCurve->apfx[i+1].y);
00421 pPolyCordBuffer[CurrentPolyIndex+2].y=SCALEY(CurrentY);
00422 }
00423 else
00424 {
00425 CurrentX=(FIXEDTOINT32(pPolyCurve->apfx[i].x)+FIXEDTOINT32(pPolyCurve->apfx[i+1].x))>>1;
00426 pPolyCordBuffer[CurrentPolyIndex+2].x=SCALEX(CurrentX);
00427 CurrentY=(FIXEDTOINT32(pPolyCurve->apfx[i].y)+FIXEDTOINT32(pPolyCurve->apfx[i+1].y))>>1;
00428 pPolyCordBuffer[CurrentPolyIndex+2].y=SCALEY(CurrentY);
00429 }
00430
00431 pPolyCordBuffer[CurrentPolyIndex+1].x=
00432
00433
00434 SCALEX(CurrentX/3) + SCALEX(((FIXEDTOINT32(pPolyCurve->apfx[i].x))<<1)/3);
00435
00436 pPolyCordBuffer[CurrentPolyIndex+1].y=
00437
00438
00439 SCALEY(CurrentY/3) + SCALEY(((FIXEDTOINT32(pPolyCurve->apfx[i].y))<<1)/3);
00440
00441 CurrentPolyIndex=CurrentPolyIndex+3;
00442
00443 }
00444 break;
00445
00446 default:
00447 delete[] pGlyphBuffer;
00448 TRACE( _T("oh my god\n"));
00449 AfxThrowMemoryException();
00450 }
00451
00452 pPosInGlyphBuffer=pPosInGlyphBuffer+sizeof(TTPOLYCURVE)+(NoOfArrayElements-1)*sizeof(POINTFX);
00453
00454 } while (pPosInGlyphBuffer<(BYTE*)pPolyHeader+ContourSize);
00455
00456 if ( (pPolyCordBuffer[FirstContourIndex].x != pPolyCordBuffer[CurrentPolyIndex-1].x) ||
00457 (pPolyCordBuffer[FirstContourIndex].y != pPolyCordBuffer[CurrentPolyIndex-1].y))
00458 {
00459 pPolyVerbBuffer[CurrentPolyIndex]=PT_LINETO | PT_CLOSEFIGURE;
00460 pPolyCordBuffer[CurrentPolyIndex]=pPolyCordBuffer[FirstContourIndex];
00461 CurrentPolyIndex++;
00462 }
00463 else
00464 {
00465 pPolyVerbBuffer[CurrentPolyIndex-1]=pPolyVerbBuffer[CurrentPolyIndex-1] | PT_CLOSEFIGURE;
00466 }
00467
00468 }
00469 delete[] pGlyphBuffer;
00470
00471 *NoPolyElements=CurrentPolyIndex;
00472 return TRUE;
00473 #else
00474 return FALSE;
00475 #endif
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 INT32 TextManager::GetDesignSize(wxDC* pDC)
00490 {
00491
00492
00493 return 2048;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 BOOL TextManager::GetLogFontFromCharDescriptor(wxDC* pDC, CharDescription& ChDesc,
00513 LOGFONT* pLogFont, INT32 LogicalHeight)
00514 {
00515 ERROR2IF(pLogFont==NULL,FALSE,"TextManager::GetLogFontFromCharDescriptor() pLogFont==NULL");
00516 ERROR2IF( pDC==NULL,FALSE,"TextManager::GetLogFontFromCharDescriptor() pDC==NULL");
00517
00518
00519 WORD FaceHandle = ChDesc.GetTypefaceHandle();
00520 CachedFontItem* pFontDataItem = FONTMANAGER->GetFont(FaceHandle);
00521 if (pFontDataItem == NULL) return FALSE;
00522
00523 ENUMLOGFONT* pEnumLogFont = pFontDataItem->GetEnumLogFont();
00524 if (pEnumLogFont == NULL) return FALSE;
00525 *pLogFont = pEnumLogFont->elfLogFont;
00526
00527 #ifndef EXCLUDE_FROM_XARALX
00528
00529 if (LogicalHeight==-1)
00530 LogicalHeight = pDC->GetDeviceCaps(LOGPIXELSY);
00531
00532
00533 pLogFont->lfHeight = -LogicalHeight;
00534 pLogFont->lfWidth = 0;
00535 pLogFont->lfWeight = ChDesc.GetBold() ? 700 : 0;
00536 pLogFont->lfItalic = ChDesc.GetItalic();
00537 #else
00538 ERROR2IF(LogicalHeight==-1, FALSE, "NYI - get device DPI");
00539 #endif
00540
00541 return TRUE;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 BOOL TextManager::GetInfoFromLogFont(FontInfo* pFontInfo, LOGFONT* pLogFont, FontClass Class)
00561 {
00562 #ifndef EXCLUDE_FROM_XARALX
00563
00564
00565
00566 String_64 Desc(pLogFont->lfFaceName);
00567 if (FONTMANAGER->CacheNamedFont(&Desc, Class)==ILLEGALFHANDLE)
00568 return FALSE;
00569
00570
00571 CDC ADC;
00572 if (ADC.CreateCompatibleDC(NULL)==0)
00573 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - CreateCompatibleDC() failed");
00574 INT32 PixelsPerInch=ADC.GetDeviceCaps(LOGPIXELSX);
00575 if (PixelsPerInch==0)
00576 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - GetDeviceCaps() failed");
00577
00578
00579 INT32 DefaultAveCharWidth=0;
00580 if (pLogFont->lfWidth!=0)
00581 {
00582 LOGFONT DefaultWidthLogFont=*pLogFont;
00583 DefaultWidthLogFont.lfWidth=0;
00584 CFont DefaultWidthFont;
00585 if (DefaultWidthFont.CreateFontIndirect(&DefaultWidthLogFont)==0)
00586 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - CreateFontIndirect() failed");
00587 CFont* pOldFont=ADC.SelectObject(&DefaultWidthFont);
00588 ERROR2IF(pOldFont==NULL,FALSE,"TextManager::GetInfoFromLogFont() - SelectObject() failed");
00589 TEXTMETRIC TM;
00590 if (ADC.GetTextMetrics(&TM)==0)
00591 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - GetTextMetrics() failed");
00592 DefaultAveCharWidth=TM.tmAveCharWidth;
00593 if (ADC.SelectObject(pOldFont)==NULL)
00594 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - SelectObject() failed");
00595 }
00596
00597
00598 CFont font;
00599 if (font.CreateFontIndirect(pLogFont)==0)
00600 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - CreateFontIndirect() failed");
00601 CFont* pOldFont=ADC.SelectObject(&font);
00602 ERROR2IF(pOldFont==NULL,FALSE,"TextManager::GetInfoFromLogFont() - SelectObject() failed");
00603 TEXTMETRIC TM;
00604 if (ADC.GetTextMetrics(&TM)==0)
00605 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - GetTextMetrics() failed");
00606 if (ADC.SelectObject(pOldFont)==NULL)
00607 ERROR2(FALSE,"TextManager::GetInfoFromLogFont() - SelectObject() failed");
00608
00609 MILLIPOINT FontSize = MulDiv(TM.tmHeight-TM.tmInternalLeading,72000,PixelsPerInch);
00610 ERROR2IF(FontSize==-1,FALSE,"TextManager::GetInfoFromLogFont() - MulDiv() failed");
00611 FIXED16 FontAspect = DefaultAveCharWidth!=0 ? Div32By32(TM.tmAveCharWidth,DefaultAveCharWidth) : 1;
00612 ERROR2IF(FontAspect==-1,FALSE,"TextManager::GetInfoFromLogFont() - MulDiv() failed");
00613
00614 pFontInfo->Handle = FONTMANAGER->GetFontHandle(&Desc, Class);
00615 pFontInfo->Size = FontSize;
00616 pFontInfo->Aspect = FontAspect;
00617 pFontInfo->Bold = pLogFont->lfWeight > FW_MEDIUM;
00618 pFontInfo->Italic = pLogFont->lfItalic != FALSE;
00619 pFontInfo->Rotation = pLogFont->lfEscapement / 10.0;
00620
00621 return TRUE;
00622 #else
00623 return FALSE;
00624 #endif
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 CharCase TextManager::ProcessCharCase(WCHAR* pChar, CharCase NewState)
00641 {
00642 ERROR2IF(pChar==NULL,Failed,"TextManager::ProcessCharCase() - pChar==NULL");
00643 ERROR2IF(NewState==Failed || NewState==UnknownType,Failed,"TextManager::ProcessCharCase() - invalid NewState");
00644 ERROR2IF(sizeof(TCHAR) != sizeof(WCHAR), Failed,"TextManager::ProcessCharCase - Unicode only");
00645
00646 CharCase OldCase=UnknownType;
00647
00648
00649 WCHAR OldCharW = *pChar;
00650 WCHAR LowerCharW = OldCharW;
00651 if ((WCHAR)camTolower(OldCharW) != OldCharW)
00652 {
00653 OldCase = Upper;
00654 LowerCharW = camTolower(OldCharW);
00655 }
00656
00657
00658 WCHAR UpperCharW = OldCharW;
00659 if ((WCHAR)camToupper(OldCharW) != OldCharW)
00660 {
00661 OldCase = Lower;
00662 UpperCharW = camToupper(OldCharW);
00663 }
00664
00665
00666 if (OldCase!=UnknownType && NewState!=Read)
00667 {
00668 if (NewState==Swap)
00669 NewState = OldCase==Lower ? Upper : Lower;
00670 WCHAR NewChar = NewState==Lower ? LowerCharW : UpperCharW;
00671 *pChar = NewChar;
00672 }
00673
00674 return OldCase;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 BOOL TextManager::GetCharWidth(wxDC* pDC, WCHAR FirstChar, WCHAR LastChar, INT32* pCharWidthsBuf)
00693 {
00694 #ifndef EXCLUDE_FROM_XARALX
00695 ERROR2IF( pDC==NULL,FALSE,"TextManager::GetCharWidth() - pDC==NULL");
00696 ERROR2IF(pCharWidthsBuf==NULL,FALSE,"TextManager::GetCharWidth() - pCharWidthsBuf==NULL");
00697
00698 BOOL ok=TRUE;
00699 if (UnicodeManager::IsUnicodeCompleteOS())
00700 ok = ::GetCharWidthW(pDC->GetSafeHdc(), FirstChar, LastChar, pCharWidthsBuf);
00701 else
00702 {
00703 UINT32 FirstMBChar = UnicodeManager::UnicodeToMultiByte(FirstChar);
00704 UINT32 LastMBChar = UnicodeManager::UnicodeToMultiByte(LastChar);
00705 ok = ::GetCharWidthA(pDC->GetSafeHdc(), FirstMBChar, LastMBChar, pCharWidthsBuf);
00706 }
00707
00708 ERROR2IF(!ok,FALSE,"TextManager::GetCharWidth() - ::GetCharWidth() failed");
00709
00710 return TRUE;
00711 #else
00712 return FALSE;
00713 #endif
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 BOOL TextManager::GetCharABCWidths(wxDC* pDC, WCHAR FirstChar, WCHAR LastChar, ABC* pCharABCsBuf)
00731 {
00732 #ifndef EXCLUDE_FROM_XARALX
00733 ERROR2IF( pDC==NULL,FALSE,"TextManager::GetABCWidths() - pDC==NULL");
00734 ERROR2IF(pCharABCsBuf==NULL,FALSE,"TextManager::GetABCWidths() - pCharABCsBuf==NULL");
00735
00736 BOOL ok=TRUE;
00737 if (UnicodeManager::IsUnicodeCompleteOS())
00738 ok = ::GetCharABCWidthsW(pDC->GetSafeHdc(), FirstChar, LastChar, pCharABCsBuf);
00739 else
00740 {
00741 UINT32 FirstMBChar = UnicodeManager::UnicodeToMultiByte(FirstChar);
00742 UINT32 LastMBChar = UnicodeManager::UnicodeToMultiByte(LastChar);
00743 ok = ::GetCharABCWidthsA(pDC->GetSafeHdc(), FirstMBChar, LastMBChar, pCharABCsBuf);
00744 }
00745
00746 ERROR2IF(!ok,FALSE,"TextManager::GetABCWidths() - ::GetCharABCWidths() failed");
00747
00748 return TRUE;
00749 #else
00750 return FALSE;
00751 #endif
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767 INT32 TextManager::GetKernCount(wxDC* pDC)
00768 {
00769 ERROR2IF(pDC==0,0,"TextManager::GetKernCount() passed null DC");
00770 #ifndef EXCLUDE_FROM_XARALX
00771 return pDC->GetKerningPairs(0, 0);
00772 #else
00773 return 0;
00774 #endif
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 bool TextManager::FillKernArray(wxDC* pDC, MillipointKerningPair* pKerningPairs, INT32 count)
00794 {
00795 ERROR2IF(pDC==0, 0, "TextManager::FillKernArray() passed null DC");
00796 ERROR3IF(count<GetKernCount(pDC), "TextManager::FillKernArray() not passed enough memory - "
00797 "kern table will be incomplete");
00798 #ifndef EXCLUDE_FROM_XARALX
00799
00800 KERNINGPAIR* pKPtmp = new KERNINGPAIR[count];
00801 if (!pKPtmp) return false;
00802
00803
00804 INT32 number = pDC->GetKerningPairs(count, pKPtmp);
00805
00806
00807 for (INT32 c = 0; c < number; ++c)
00808 {
00809 pKerningPairs[c].wFirst = pKPtmp[c].wFirst;
00810 pKerningPairs[c].wSecond = pKPtmp[c].wSecond;
00811 pKerningPairs[c].iKernAmount = pKPtmp[c].iKernAmount;
00812 }
00813
00814
00815 delete pKPtmp;
00816
00817
00818 if (number == 0 && GetKernCount(pDC) != 0)
00819 {
00820 ERROR3("Error reading kerning data");
00821 return false;
00822 }
00823 else
00824 {
00825 return true;
00826 }
00827 #else
00828 return FALSE;
00829 #endif
00830 }