fontpgen.cpp

Go to the documentation of this file.
00001 // $Id: fontpgen.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // FontPGen.cpp - the Font Previewer Thumbnail Generation class
00099 
00100 #include "camtypes.h"
00101 
00102 #ifndef EXCLUDE_GALS
00103 #include "bfxalu.h"
00104 #include "textfuns.h"
00105 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 //#include "bitmap.h"              - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "bitmpinf.h"
00108 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "grndrgn.h"
00110 #include "wbitmap.h"
00111 //#include "outptdib.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "paths.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 //#include "trans2d.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "fontpgen.h"
00115 #include "progress.h"
00116 //#include "sgallery.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00117 #include "dlgcol.h"
00118 #include "unicdman.h"
00119 
00120 //#include "thumb.h" // not normally needed - in camtypes.h [AUTOMATICALLY REMOVED]
00121 
00122 // Implement the dynamic class bits...
00123 CC_IMPLEMENT_DYNAMIC(StringToBitmap, BitmapEffectBase)
00124 
00125 // This line mustn't go before any CC_IMPLEMENT_... macros
00126 #define new CAM_DEBUG_NEW
00127 
00128 /***********************************************************************************/
00129 
00130 // Background font thumbnail colour
00131 const INT32 S2BMP_BACKGROUND_COLOUR = 0x00ffffff; // white
00132 const INT32 S2BMP_FOREGROUND_COLOUR = 0x00000000; // black
00133 
00134 // Antialias the previews ?
00135 const BOOL S2BMP_ANTIALIAS = TRUE;
00136 
00137 // Mark's magic number for his GetBezierFromChar routine
00138 const INT32 S2BMP_MAGIC = 2000;
00139 
00140 /***********************************************************************************************
00141 
00142 >   class StringToBitmap
00143 
00144     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00145     Created:    09/02/95
00146     Purpose:    Generation of anti-aliased font-string bitmaps for the font installer / de-installer
00147 
00148     SeeAlso:    BfxALU.cpp
00149 
00150 ***********************************************************************************************/
00151 
00152 StringToBitmap::StringToBitmap(void)
00153 {
00154 }
00155 
00156 /************************************************************************************/
00157 
00158 StringToBitmap::~StringToBitmap(void)
00159 {
00160 }
00161 
00162 /************************************************************************************
00163 
00164 >   BOOL StringToBitmap::SaveBitmap(KernelBitmap *Bitmap, PathName *Path)
00165     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00166     Created:    13/2/95
00167     Inputs:     Bitmap - Pointer to a kernel bitmap
00168                 Path - Pathname to save bitmap under
00169     Outputs:    Returns TRUE if things went OK.
00170     Purpose:    Saves the given kernel bitmap to a file...
00171                 This should only be used for saving thumbnails, and has only
00172                 been tested with 32 bpp files so far...
00173 
00174 ********************************************************************************************/
00175 
00176 BOOL StringToBitmap::SaveBitmap(KernelBitmap *Bitmap, PathName *Path)
00177 {
00178     BOOL ok = TRUE;
00179 
00180 //  if(Bitmap->GetBPP() != 32)
00181 //  {
00182 //      TRACEUSER( "Richard", _T("Can only save converted 32bpp thumbnails"));
00183 //      return FALSE;
00184 //  }
00185 
00186     // Get the file ready for outputting
00187     CCDiskFile OutputFile;
00188     PathName TmpPath(*Path);
00189     ok = OutputFile.open(TmpPath, ios::out | ios::binary);
00190     if(!ok) ERROR3("s2bmp OutputFile.open returned false");
00191     if(!ok) return FALSE;
00192     
00193     
00194     // Always output at 8bpp or 32bpp
00195     const UINT32 OutputDepth = Bitmap->GetBPP();
00196 
00197     if(OutputDepth != 8 && OutputDepth != 32)
00198     {
00199         ERROR3("Wrong bpp for saving bmp in fontpgen");
00200         return FALSE;
00201     }
00202 
00203     // Extract the header info and write it to the file first       
00204     BitmapInfo Info;
00205     BitmapInfo *lpInfo = &Info;
00206     ok = Bitmap->ActualBitmap->GetInfo(lpInfo);
00207     if(!ok) ERROR3("s2bmp Bitmap->ActualBitmap->GetInfo(lpInfo) returned false");
00208     if(!ok) return FALSE;
00209 
00210     LPBITMAPINFOHEADER pBMI =&(((WinBitmap *)(Bitmap->ActualBitmap))->BMInfo->bmiHeader); 
00211     ok = (pBMI!=NULL);
00212     if(!ok) ERROR3("s2bmp pBMI!=NULL returned false");
00213     if(!ok) return FALSE;
00214 
00215     UINT32 Ysize = pBMI->biHeight;
00216 
00217     // Sort the palette out
00218     LPLOGPALETTE lpPalette = NULL;
00219 
00220     DWORD space[258]; // bodge (256 entries + 2 DWORDS)
00221     if(OutputDepth<=8)
00222     {
00223         //DWORD *space = malloc(sizeof(DWORD) * (2<<OutputDepth)+4); // bodge!
00224         lpPalette = (LPLOGPALETTE)(void *)(space);
00225         memcpy(lpPalette->palPalEntry /*dest*/, (pBMI+1/*ptr arith*/)/*src*/, (pBMI->biClrUsed)*sizeof(DWORD));
00226         lpPalette->palVersion = 0x300;
00227         lpPalette->palNumEntries = (unsigned short)(pBMI->biClrUsed);
00228     }
00229 
00230     // Set up the compression flag only if the output depth is correct
00231     UINT32 Compress = BI_RGB;
00232 //  if (OutputDepth==4) Compress = BI_RLE4;
00233 //  if (OutputDepth==8) Compress = BI_RLE8;
00234                                                                                          
00235     // Write header to output file
00236     OutputDIB DestDIB;
00237 
00238     BeginSlowJob(100, TRUE, &(String_64)"Creating thumbnail");
00239 
00240     ok = DestDIB.StartFile( &OutputFile, pBMI, lpPalette,
00241                             OutputDepth,                    // actual file depth
00242                             Compress,                       // compression (BI_RGB = none)
00243                             (UINT32) Ysize,                 // all of it
00244                             100);                           // size of progress bar
00245 
00246     if(!ok) ERROR3("DestDIB.StartFile returned false");
00247     if(!ok) EndSlowJob();
00248     if(!ok) return FALSE;
00249 
00250     // write main data to the output file
00251     ok = DestDIB.WriteBlock(0, Ysize, ((WinBitmap *)(Bitmap->ActualBitmap))->BMBytes, (UINT32) Bitmap->GetBPP());
00252     if(!ok) ERROR3("DestDIB.WriteBlock returned false");
00253     if(!ok) EndSlowJob();
00254     if(!ok) return FALSE;
00255 
00256     // Tidy up the file before killing the object
00257     ok = DestDIB.TidyUp();
00258 
00259     EndSlowJob();
00260 
00261     if(!ok) ERROR3("DestDIB.TidyUp returned false");
00262     if(!ok) return FALSE;
00263 
00264     return TRUE;
00265 }
00266 
00267 /************************************************************************************
00268 
00269 >   BOOL StringToBitmap::BlankBitmap(UINT32 Xsize, UINT32 Ysize, UINT32 BPP, UINT32 BackCol,
00270                                  KernelBitmap **BM)
00271     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00272     Created:    16/2/95
00273 
00274     Inputs:     Xsize - Width (in pixels) of thumbnail to generate
00275                 Ysize - Height (in pixels) of thumbnail to generate
00276                 BPP - Bits Per Pixel for output bitmap... 32 or 8 are sensible
00277                 BackCol - Colour for bitmap background
00278     Returns:    BM - returns a pointer to a bitmap which we allocate here
00279     Outputs:    Returns TRUE if things went OK.
00280 
00281     Purpose:    Creates a bitmap of the specified size, and blanks it with the given
00282                 colours... Even gives it a greyscale palette if <= 8bpp.
00283                 
00284 ********************************************************************************************/
00285 
00286 BOOL StringToBitmap::BlankBitmap(UINT32 Xsize, UINT32 Ysize, UINT32 BPP, UINT32 BackCol,
00287                                  KernelBitmap **BM)
00288 {
00289     // Nowt wrong yet
00290     BOOL ok = TRUE;     
00291 
00292     // Create a new (temp) bitmap of desired size
00293     INT32 Width = Xsize;
00294     INT32 Height = Ysize;
00295     INT32 Depth = BPP;
00296     INT32 DPI = 96;
00297     KernelBitmap * Bitmap = new KernelBitmap(Width,Height,Depth,DPI, TRUE);
00298     Error::ClearError();
00299 
00300     // Check it 'worked'
00301     ok = ( (Bitmap != NULL) && (Bitmap->ActualBitmap != NULL)
00302             && (((WinBitmap *)(Bitmap->ActualBitmap))->BMInfo != NULL)
00303             && (((WinBitmap *)(Bitmap->ActualBitmap))->BMBytes != NULL) );
00304 
00305     ERROR3IF(!ok, "BlankBitmap can't allocate space for bitmap");
00306     if(ok)
00307     {       
00308         // If the bitmap is capable of having a palette, give it a nice even greyscale one.
00309         if(BPP <= 8)
00310         {
00311             // How many entries in the palette ?
00312             DWORD Entries = ((WinBitmap*)Bitmap->ActualBitmap)->BMInfo->bmiHeader.biClrUsed;
00313             if (Entries==0) Entries = 1<<BPP;
00314             RGBQUAD Quad;
00315             INT32 i;
00316             BYTE Value;
00317 
00318             // Factor by which to multiply the counter to obtain an even spread
00319             INT32 Mult = 256 / Entries;
00320 
00321             ((WinBitmap*)Bitmap->ActualBitmap)->BMInfo->bmiHeader.biClrImportant = Entries;
00322 
00323             for(i=0; i < (INT32)Entries; i++)
00324             {
00325                 Value = i * Mult;
00326 
00327                 if(Value > 255) Value = 255;
00328 
00329                 // Fill up a quad with a grey-scale entry
00330                 Quad.rgbBlue = Value;
00331                 Quad.rgbGreen = Value;
00332                 Quad.rgbRed = Value;
00333                 Quad.rgbReserved = 0;
00334 
00335                 // Poke the quad into the wbitmap
00336                 ((WinBitmap*)Bitmap->ActualBitmap)->BMInfo->bmiColors[i] = Quad;
00337                                  
00338             }
00339         }
00340 
00341         // Set the bfx accumulator to our new bitmap
00342         ok = ALU->SetA(Bitmap);
00343         ERROR3IF(!ok, "BlankBitmap ALU->SetA returned false");
00344         if(ok)
00345         {
00346             // Fill the bitmap with the specified fill colour
00347             ok = ALU->ZeroA(BackCol);
00348             ERROR3IF(!ok, "BlankBitmap ALU->ZeroA returned false");
00349         }
00350     }
00351 
00352     if(!ok && Bitmap != NULL)
00353     {
00354         delete Bitmap;
00355         Bitmap = NULL;
00356     }
00357 
00358     *BM = Bitmap;
00359     return ok;
00360 }
00361 
00362 /********************************************************************************************
00363 
00364 >   BOOL StringToBitmap::TTFAddString(String_256 *text, UINT32 Xsize, UINT32 Ysize, UINT32 DPI,
00365             PLOGFONT pLogFont, INT32 IntLeading, KernelBitmap **BM, UINT32 ForeColour)
00366     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00367     Created:    13/2/95
00368     Inputs:     text - pointer to a string of thumbnail text
00369                 Xsize - Width (in pixels) of thumbnail to generate
00370                 Ysize - Height (in pixels) of thumbnail to generate
00371                 DPI - DPI of bitmap to add string to
00372                 pLogFont - Pointer to a log font structure of the font to use
00373                 IntLeading - Internal leading valoue of font, as given in the NewTextMetrics
00374                 BM - Pointer to a pointer to a kernel bitmap to return the result in
00375                 ForeColour - Foreground colour of text
00376 
00377     Outputs:    Returns TRUE if things went OK.
00378 
00379     Purpose:    This is the main routine for sticking strings in bitmaps...
00380                 Using the supplied info we generate a path, and plot this into the
00381                 bitmap, which has already been set up to the required size...
00382                 
00383 ********************************************************************************************/
00384 
00385 BOOL StringToBitmap::TTFAddString(String_256 *text, UINT32 Xsize, UINT32 Ysize, UINT32 DPI, PLOGFONT pLogFont,
00386                                  INT32 IntLeading, KernelBitmap **BM, UINT32 ForeColour)
00387 {
00388     KernelBitmap *Bitmap = *BM;
00389 
00390 /*  HDC ScreenDC = CreateCompatibleDC(NULL);
00391     if (ScreenDC == NULL)
00392     {
00393         ERROR3("StringToBitmap::AddString: Unable to create screen DC");
00394         return FALSE;
00395     }*/
00396 
00397     CDC SysDisplay;
00398     BOOL ok=SysDisplay.CreateCompatibleDC(NULL);
00399     if(!ok)
00400     {
00401         //DeleteDC(ScreenDC);
00402         ERROR3("StringToBitmap::TTF AddString: Unable to create CDC");
00403         return FALSE;
00404     }
00405 
00406     HDC ScreenDC = SysDisplay.m_hDC;
00407     
00408     // bodge to get things working with GetBezierFromChar
00409     INT32 OldlfHeight = pLogFont->lfHeight;
00410     pLogFont->lfHeight = -(pLogFont->lfHeight - IntLeading);
00411     
00412     UINT32 CurrentPathSizeAlloc = 0;
00413     Trans2DMatrix *pTransform = NULL; 
00414     DocCoord *pPathCoords = NULL;
00415 
00416     Path *pPath = NULL;
00417     //pPath = new Path(); 
00418 
00419     DocCoord *pPolyCordBuffer = NULL;
00420     PathVerb *pPolyVerbBuffer = NULL;
00421     UINT32 TextLength = (UINT32)text->Length();
00422     SIZE StringSize={0,0};
00423             
00424     // Get handle of font
00425     
00426 //  HFONT hNewFont = CreateFontIndirect(pLogFont);
00427 //  HGDIOBJ hOldFont = SelectObject(ScreenDC, hNewFont);
00428 
00429     CFont UnHintedCFont;
00430     if(!UnHintedCFont.CreateFontIndirect(pLogFont))
00431     {
00432         SysDisplay.DeleteDC();
00433         pLogFont->lfHeight = OldlfHeight;
00434         return FALSE;
00435     }
00436     
00437     CFont* pOldCFont=SysDisplay.SelectObject(&UnHintedCFont);
00438 
00439     // Get the default character to use if a charater is not present in the font.
00440     WCHAR FontDefaultCharacter = (unsigned char)'?';
00441     TEXTMETRIC FontTextData;
00442 #ifdef _UNCCODE
00443     if (SysDisplay.GetTextMetrics(&FontTextData))
00444         FontDefaultCharacter = FontTextData.tmDefaultChar;
00445 #else
00446     if (SysDisplay.GetTextMetrics(&FontTextData))
00447         FontDefaultCharacter = (unsigned char)FontTextData.tmDefaultChar;
00448 #endif
00449     
00450     // Work out a nice scaling factor so the font fits in the bitmap ok...
00451     
00452     // Not 32 ?
00453     GetTextExtentPoint(ScreenDC, *text, TextLength, &StringSize);
00454 
00455     if(StringSize.cy == 0)
00456     {
00457         SysDisplay.SelectObject(pOldCFont);
00458         SysDisplay.DeleteDC();
00459         pLogFont->lfHeight = OldlfHeight;
00460         return FALSE;
00461     }
00462 
00463     //ERROR3IF(!ok, "Initial GetTextExtentPoint32() failed");
00464     double YScale = ((double)Ysize / (double)StringSize.cy) / (double)2;
00465     double XScale = YScale;
00466 
00467     // Shift thumbnail upwards, and scale down a bit - to get the g's looking right
00468     // One or two fonts require this reducing (their tops are clipped), 72000/100 is
00469     // about right for most of them though...
00470     // Note the external previews were done with 72000/220 for Matrix and 72000/140 for
00471     // the capital only fonts.
00472     double YShift = 72000/100;//72000/80;
00473 
00474     YScale = (YScale * 78) / 100;
00475     XScale = (XScale * 78) / 100;
00476 
00477     if(!text->IsEmpty())
00478     {
00479         const TCHAR* pCurrentChar = (const TCHAR*)(*text);
00480 
00481         while (ok && *pCurrentChar!=0)
00482         {
00483             // Get the current character as Unicode.
00484 #ifdef _UNICODE
00485             WCHAR wchr = *pCurrentChar;     // pCurrentChar is a pointer to WCHAR in _UNICODE builds
00486 #else
00487             UINT32 CharToConvert = 0;
00488             if (UnicodeManager::IsDBCSLeadByte(*pCurrentChar))
00489                 CharToConvert = UnicodeManager::ComposeMultiBytes(*pCurrentChar, *(pCurrentChar+1));
00490             else
00491                 CharToConvert = (unsigned char)(*pCurrentChar);
00492             WCHAR wchr = UnicodeManager::MultiByteToUnicode(CharToConvert);
00493 #endif
00494 
00495             // Get positioning information for this character
00496             ok = GetTextExtentPoint(ScreenDC, *text, (pCurrentChar-(TCHAR*)(*text)), &StringSize);
00497             ERROR3IF(!ok, "GetTextExtentPoint32() failed");
00498             if (!ok) break;
00499                          
00500             // Get the characters path
00501             DWORD PathSize = 0;                         
00502             ok = TextManager::GetBezierFromChar(&SysDisplay, wchr, pLogFont, &PathSize, (POINT *)NULL, (BYTE *)NULL);
00503             if (!ok)
00504             {
00505                 wchr = FontDefaultCharacter;
00506                 ok = TextManager::GetBezierFromChar(&SysDisplay, wchr, pLogFont, &PathSize, (POINT *)NULL, (BYTE *)NULL);
00507             }
00508             ERROR3IF(!ok, "GetBezierFromChar returned false");
00509             if (!ok) break;
00510 
00511             // Pointer to an array of path coordinates
00512             if(pPolyCordBuffer == NULL)
00513             {
00514                 TRY
00515                 {
00516                     pPolyCordBuffer = new DocCoord[PathSize];
00517                 }
00518                 CATCH (CMemoryException, e)
00519                 {
00520                     pPolyCordBuffer = NULL;
00521                     /*ERROR(_R(IDS_OUT_OF_MEMORY), FALSE);*/
00522                 }
00523                 END_CATCH
00524             }
00525 
00526             // Pointer to an array of path verbs
00527             if(pPolyVerbBuffer == NULL)
00528             {
00529                 TRY
00530                 {
00531                     pPolyVerbBuffer = new PathVerb[PathSize];
00532                 }
00533                 CATCH (CMemoryException, e)
00534                 {
00535                     pPolyVerbBuffer = NULL;
00536                     /*ERROR(_R(IDS_OUT_OF_MEMORY), FALSE);*/
00537                 }
00538                 END_CATCH
00539             }
00540                                             
00541             if (pPolyCordBuffer == NULL || pPolyVerbBuffer == NULL)
00542             {
00543                 ok = FALSE;
00544                 break;
00545             }
00546 
00547             CurrentPathSizeAlloc = PathSize;
00548 
00549             // Fill up the buffers until they're bursting with fontyness
00550             ok = TextManager::GetBezierFromChar(&SysDisplay, wchr, pLogFont, &PathSize, (POINT *)pPolyCordBuffer,
00551                                                                             (BYTE *)pPolyVerbBuffer);
00552             if(!ok) TRACEUSER( "Richard", _T("GetBezierFromChar returned false in second phase...\n"));
00553             if(!ok) break;
00554 
00555             // Spaces set PathSize to zero
00556             if((PathSize > 0)/* && (pPath != NULL)*/)
00557             {               
00558                 pPath = new Path(); 
00559                 pPath->Initialise(PathSize, 12);
00560                 pPath->CopyPathDataFrom(pPolyCordBuffer, pPolyVerbBuffer, PathSize, TRUE);
00561 
00562                 // Major bodge at present with the x spacing...
00563                 Matrix scale(XScale, 0, 0, YScale, (INT32)((XScale*StringSize.cx*72000)/(double)DPI), (INT32)YShift);
00564                 
00565                 pTransform = new Trans2DMatrix(scale);      
00566                 pPathCoords = pPath->GetCoordArray();                                
00567                 pTransform->Transform( pPathCoords, pPath->GetNumCoords() );
00568                 delete pTransform;
00569 
00570                 pPath->InitialiseFlags();
00571     
00572                 ok = ALU->GradFillPath(pPath, ForeColour, ForeColour, 0, 0, 0,/*Xsize/2,*/ Ysize, S2BMP_ANTIALIAS);
00573                 ERROR3IF(!ok, "Gradfillpath returned false");
00574                 if(!ok) break;
00575 
00576                 delete pPath;
00577             }
00578 
00579             // S2BMP_MAGIC is the worderfully fabby constant that mark's getbezierfromchar returns
00580             // Theory goes that he's going to sort this out sometime...
00581             if(CurrentPathSizeAlloc != S2BMP_MAGIC)
00582             {
00583                 delete []pPolyCordBuffer;
00584                 delete []pPolyVerbBuffer;
00585 
00586                 pPolyCordBuffer = NULL;
00587                 pPolyVerbBuffer = NULL;
00588                 CurrentPathSizeAlloc = 0;
00589             }
00590 
00591             pPath = NULL;
00592             pTransform = NULL;
00593 
00594             pCurrentChar = camStrinc(pCurrentChar);
00595         }
00596     }
00597 
00598     // We don't want any memory left dangling about...
00599     if(pPolyCordBuffer != NULL) delete []pPolyCordBuffer;
00600     if(pPolyVerbBuffer != NULL) delete []pPolyVerbBuffer;
00601     if(pPath != NULL) delete pPath;
00602     if(pTransform != NULL) delete pTransform;                          
00603 
00604     // Revert back to old font
00605 //  SelectObject(ScreenDC, hOldFont);
00606 //  DeleteObject(hNewFont);
00607 
00608     //Lets restore the DC font status
00609     SysDisplay.SelectObject(pOldCFont);
00610 //  DeleteObject(UnHintedCFont);
00611                               
00612 //  DeleteDC(ScreenDC);
00613     SysDisplay.DeleteDC();
00614 
00615     pLogFont->lfHeight = OldlfHeight;
00616 
00617     return ok;
00618 }
00619 
00620 
00621 /********************************************************************************************
00622 
00623 >   BOOL StringToBitmap::AddString(String_256 *text, UINT32 Xsize, UINT32 Ysize, UINT32 DPI,
00624             PLOGFONT pLogFont, INT32 IntLeading, KernelBitmap **BM, UINT32 ForeColour, FontClass Type)
00625     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00626     Created:    13/2/95
00627     Inputs:     text        - pointer to a string of thumbnail text
00628                 Xsize       - Width (in pixels) of thumbnail to generate
00629                 Ysize       - Height (in pixels) of thumbnail to generate
00630                 DPI         - DPI of bitmap to add string to
00631                 pLogFont    - Pointer to a log font structure of the font to use
00632                 IntLeading  - Internal leading valoue of font, as given in the NewTextMetrics
00633                 BM          - Pointer to a pointer to a kernel bitmap to return the result in
00634                 ForeColour  - Foreground colour of text
00635                 Type        - FontClass of Font -> FC_TRUETYPE, or FC_ATM
00636 
00637     Outputs:    Returns TRUE if things went OK.
00638 
00639     Purpose:    This is the main routine for sticking strings in bitmaps...
00640                 Using the supplied info we generate a path, and plot this into the
00641                 bitmap, which has already been set up to the required size...
00642                 
00643 ********************************************************************************************/
00644 
00645 BOOL StringToBitmap::AddString(String_256 *text, UINT32 Xsize, UINT32 Ysize, UINT32 DPI, PLOGFONT pLogFont,
00646                                  INT32 IntLeading, KernelBitmap **BM, UINT32 ForeColour, FontClass Type)
00647 {
00648     ERROR3IF(text == NULL, "StringToBitmap::AddString given null text pointer");
00649     ERROR3IF(pLogFont == NULL, "StringToBitmap::AddString given null logfont pointer");
00650     ERROR3IF(BM == NULL, "StringToBitmap::AddString given null bmp pointer");
00651     if(text == NULL || pLogFont == NULL || BM == NULL)
00652         return FALSE;
00653 
00654     KernelBitmap *Bitmap = *BM;
00655 
00656     FontInfo info;
00657     BOOL ok=TextManager::GetInfoFromLogFont(&info, pLogFont, Type);
00658     if (!ok)
00659     {
00660         ERROR3("StringToBitmap::ATMAddString problems getting font handle");        
00661         return FALSE;
00662     }
00663 
00664     BOOL Bold = info.Bold;
00665     BOOL Italic = info.Italic;
00666     WORD TypeFaceHandle = info.Handle;
00667 
00668     CDC SysDisplay;
00669     ok=SysDisplay.CreateCompatibleDC(NULL);
00670     if(!ok)
00671     {
00672         ERROR3("StringToBitmap::AddString: Unable to create CDC");
00673         return FALSE;
00674     }
00675 
00676     HDC ScreenDC = SysDisplay.m_hDC;
00677 
00678     Trans2DMatrix *pTransform = NULL; 
00679     UINT32 ChNum = 0;
00680     DocCoord *pPathCoords = NULL;
00681 
00682     Path *pPath = NULL;
00683 
00684     DocCoord *pPolyCordBuffer = NULL;
00685     PathVerb *pPolyVerbBuffer = NULL;
00686     UINT32 TextLength = (UINT32)text->Length();
00687     SIZE StringSize={0,0};
00688             
00689     // Get handle of font
00690     LOGFONT CharLogFont;
00691     CharDescription DummyChar(TEXT('A'), TypeFaceHandle, Bold, Italic);
00692     ok=TextManager::GetLogFontFromCharDescriptor(&SysDisplay, DummyChar, &CharLogFont);
00693 
00694     CFont UnHintedCFont;
00695     if(!UnHintedCFont.CreateFontIndirect(&CharLogFont))
00696     {
00697         SysDisplay.DeleteDC();
00698         return FALSE;
00699     }
00700 
00701     CFont* pOldCFont=SysDisplay.SelectObject(&UnHintedCFont);
00702     
00703     // Work out a nice scaling factor so the font fits in the bitmap ok...
00704     // Not 32 ?
00705     if(!GetTextExtentPoint(ScreenDC, *text, TextLength, &StringSize))
00706     {
00707         SysDisplay.SelectObject(pOldCFont);
00708         SysDisplay.DeleteDC();
00709         return FALSE;
00710     }
00711 
00712     if(StringSize.cy == 0)
00713     {
00714         SysDisplay.SelectObject(pOldCFont);
00715         SysDisplay.DeleteDC();
00716         return FALSE;
00717     }
00718 
00719     double YScale = ((double)Ysize / (double)StringSize.cy) / (double)2;
00720     YScale = (YScale * 78) / 100;
00721     double XScale = YScale;
00722     double XSpacing = (XScale * 72000) / (double)DPI;
00723 
00724     // Shift thumbnail upwards, and scale down a bit - to get the g's looking right
00725     // One or two fonts require this reducing (their tops are clipped), 72000/100 is
00726     // about right for most of them though...
00727     // Note the external previews were done with 72000/220 for Matrix and 72000/140 for
00728     // the capital only fonts.
00729     double YShift = 72000/100;//72000/80;
00730 
00731     UINT32 NumCoords = 0;
00732 
00733     if(!text->IsEmpty())
00734     {
00735         const TCHAR* pCurrentChar = (const TCHAR*)(*text);
00736 
00737         while (ok && *pCurrentChar!=0)
00738         {
00739             // Get the current character as Unicode.
00740 #ifdef _UNICODE
00741             WCHAR wchr = *pCurrentChar;     // pCurrentChar is a pointer to WCHAR in _UNICODE builds
00742 #else
00743             UINT32 CharToConvert = 0;
00744             if (UnicodeManager::IsDBCSLeadByte(*pCurrentChar))
00745                 CharToConvert = UnicodeManager::ComposeMultiBytes(*pCurrentChar, *(pCurrentChar+1));
00746             else
00747                 CharToConvert = (unsigned char)(*pCurrentChar);
00748             WCHAR wchr = UnicodeManager::MultiByteToUnicode(CharToConvert);
00749 #endif
00750 
00751             // Get positioning information for this character
00752             ok = GetTextExtentPoint(ScreenDC, *text, (pCurrentChar-(TCHAR*)(*text)), &StringSize);
00753             ERROR3IF(!ok, "GetTextExtentPoint32() failed");
00754             if (!ok) break;
00755 
00756             CharDescription CharDesc(wchr, TypeFaceHandle, Bold, Italic);
00757             NumCoords = 0;
00758 
00759             ok = OILFontMan::GetCharPath(Type, CharDesc, &pPolyCordBuffer, &pPolyVerbBuffer, &NumCoords, NULL);//&SysDisplay);
00760             if(!ok) break;
00761 
00762             // Spaces set PathSize to zero
00763             if((NumCoords > 0)/* && (pPath != NULL)*/)
00764             {               
00765                 pPath = new Path(); 
00766                 pPath->Initialise(NumCoords, 12);
00767                 pPath->CopyPathDataFrom(pPolyCordBuffer, pPolyVerbBuffer, NumCoords, TRUE);
00768 
00769                 // Major bodge at present with the x spacing...
00770                 Matrix scale(XScale, 0, 0, YScale, (INT32)(XSpacing * (double)StringSize.cx), (INT32)YShift);
00771                 
00772                 pTransform = new Trans2DMatrix(scale);      
00773                 pPathCoords = pPath->GetCoordArray();                                
00774                 pTransform->Transform( pPathCoords, pPath->GetNumCoords() );
00775                 delete pTransform;
00776 
00777                 pPath->InitialiseFlags();
00778 
00779                 ok = ALU->GradFillPath(pPath, ForeColour, ForeColour, 0, 0, 0,/*Xsize/2,*/ Ysize, S2BMP_ANTIALIAS);
00780                 ERROR3IF(!ok, "Gradfillpath returned false");
00781                 if(!ok) break;
00782 
00783                 delete pPath;
00784             }
00785 
00786             pPath = NULL;
00787             pTransform = NULL;
00788   
00789             pCurrentChar = camStrinc(pCurrentChar);
00790         }
00791     }
00792 
00793     // We don't want any memory left dangling about...
00794     if(pPath != NULL) delete pPath;
00795     if(pTransform != NULL) delete pTransform;                          
00796 
00797     //Lets restore the DC font status
00798     SysDisplay.SelectObject(pOldCFont);
00799     SysDisplay.DeleteDC();
00800 
00801     return ok;
00802 }
00803 
00804 /********************************************************************************************
00805 
00806 >   BOOL StringToBitmap::MakeBitmap(String_256 *text, UINT32 Xsize, UINT32 Ysize, UINT32 BPP, UINT32 DPI,
00807             PLOGFONT pLogFont, INT32 IntLeading, KernelBitmap **BM, FontClass Type, PathName *Filename)
00808     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00809     Created:    13/2/95
00810     Inputs:     text - pointer to a string of thumbnail text
00811                 Xsize - Width (in pixels) of thumbnail to generate
00812                 Ysize - Height (in pixels) of thumbnail to generate
00813                 BPP - Bits per pixel of image to create
00814                 DPI - DPI of bitmap
00815                 pLogFont - Pointer to a log font structure of the font to use
00816                 IntLeading - Internal leading value for the font. Given by the font's NewTextMetrics
00817                 BM - Pointer to a pointer to a kernel bitmap to return the result in
00818                 Type - Type of font - Truetype or ATM
00819                 Filename - Pointer to a filename for the thumbnail to be saved with (optional)
00820     Returns:    BM - Pointer to a pointer to a kernel bitmap to return the result in
00821     Outputs:    Returns TRUE if things went OK.
00822 
00823     Purpose:    Give me a string of text, some bitmap dimensions and a couple of font
00824                 specifications, and I'll go away and generate a thumbnail using the 
00825                 text and font specified.
00826 
00827                 I can also save bitmaps out, that's where the Filename comes in. This
00828                 can be left out, or passed as NULL if you don't want this...
00829                 
00830 ********************************************************************************************/
00831                     
00832 BOOL StringToBitmap::MakeBitmap(String_256 *text, UINT32 Xsize, UINT32 Ysize, UINT32 BPP, UINT32 DPI,
00833             PLOGFONT pLogFont, INT32 IntLeading, KernelBitmap **BM, FontClass Type, PathName *Filename)
00834 {
00835     ERROR3IF(text == NULL, "StringToBitmap::MakeBitmap given null text pointer");
00836     ERROR3IF(pLogFont == NULL, "StringToBitmap::MakeBitmap given null logfont pointer");
00837     ERROR3IF(BM == NULL, "StringToBitmap::MakeBitmap given null bmp pointer");
00838     if(text == NULL || pLogFont == NULL || BM == NULL)
00839         return FALSE;
00840 
00841     // Nowt wrong yet
00842     BOOL ok = TRUE;     
00843 
00844     // Our temporary bitmap pointer     
00845     KernelBitmap *Bitmap = NULL;
00846 
00847 #if 0
00848     // work out the current window background colour so we don't get white rectangles round our items
00849     DialogColourInfo DCol;
00850     DocColour DialogBack = DCol.TextBack(); //DialogBack();
00851     INT32 Red, Green, Blue; 
00852     DialogBack.GetRGBValue(&Red, &Green, &Blue);    
00853     DWORD BackColRef = (DWORD) Red;
00854     BackColRef |= ((DWORD)Green) << 8;
00855     BackColRef |= ((DWORD)Blue) << 16;
00856 #endif
00857 
00858     // Allocate memory and blank it
00859     // We always create a 32bpp bmp now, and convert it later...
00860     if(!BlankBitmap(Xsize, Ysize, 32, /*BackColRef*/S2BMP_BACKGROUND_COLOUR, &Bitmap))
00861     {
00862         ERROR3("BlankBitmap returned false");
00863         return FALSE;
00864     }
00865 
00866     // Actually store the bitmap pointer in the class
00867     *BM = Bitmap;
00868 
00869     // Now lets put the string in the bitmap (so help me god)
00870     if(!AddString(text, Xsize, Ysize, DPI, pLogFont, IntLeading, &Bitmap, S2BMP_FOREGROUND_COLOUR, Type))
00871     {
00872         Error::ClearError();
00873         ERROR3("Addstring returned false");
00874         return FALSE;
00875     }
00876     Error::ClearError();
00877 
00878     // Convert the 32bpp thumbnail into an 8bpp one 
00879     if(BPP == 8)
00880     {
00881         ALU->SetB(Bitmap);
00882         KernelBitmap *pNewBitmap = NULL;
00883         //if(ALU->MakeGreyscale(&pNewBitmap))
00884         if(ALU->MakeGreyscale32to8(&pNewBitmap))
00885         {
00886             if(pNewBitmap != NULL)
00887             {
00888                 delete Bitmap;
00889                 ContoneFontBitmap(pNewBitmap);
00890                 Bitmap = pNewBitmap;
00891                 *BM = Bitmap;
00892             }
00893         }
00894     }
00895 
00896     // Do we want to save the thumbnail to a file ?
00897     if(Filename != NULL)
00898     {
00899         // Save the bitmap
00900         ok = StringToBitmap::SaveBitmap(Bitmap, Filename);
00901         if(!ok) TRACEUSER( "Richard", _T("Failed to save thumbnail file"));
00902     }               
00903 
00904     return ok;
00905 }
00906 
00907 /********************************************************************************************
00908 
00909 >   static BOOL StringToBitmap::ContoneFontBitmap(KernelBitmap *pBitmap)
00910 
00911     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00912     Created:    12/12/95
00913 
00914     Inputs:     pBitmap - Pointer to the KernelBitmap for the preview (must be 8bpp, etc)
00915     Returns:    TRUE if things went ok...
00916 
00917     Purpose:    Given a Greyscale font preview, contone it to blend in with the background
00918                 of the gallery...
00919                 
00920 ********************************************************************************************/
00921 
00922 BOOL StringToBitmap::ContoneFontBitmap(KernelBitmap *pBitmap)
00923 {
00924     ERROR3IF(pBitmap == NULL, "StringToBitmap::ContoneFontBitmap given a NULL param");
00925 
00926     if(pBitmap->GetBPP() != 8)
00927         return FALSE;
00928 
00929     if(!SuperGallery::UseFixedColourSet)
00930     {
00931         RGBQUAD Pal;
00932         RGBQUAD Start;
00933         RGBQUAD End;
00934         INT32 Red, Green, Blue; 
00935         DialogColourInfo RedrawColours;
00936 
00937         DocColour TmpCol = RedrawColours.TextFore();
00938         TmpCol.GetRGBValue(&Red, &Green, &Blue);    
00939 
00940         Start.rgbRed = (BYTE)Red;
00941         Start.rgbGreen = (BYTE)Green;
00942         Start.rgbBlue = (BYTE)Blue;
00943         Start.rgbReserved = 0;
00944 
00945         TmpCol = RedrawColours.TextBack();
00946         TmpCol.GetRGBValue(&Red, &Green, &Blue);    
00947 
00948         End.rgbRed = (BYTE)Red;
00949         End.rgbGreen = (BYTE)Green;
00950         End.rgbBlue = (BYTE)Blue;
00951         End.rgbReserved = 0;
00952 
00953         RGBQUAD *DestPal = ((WinBitmap *)pBitmap->ActualBitmap)->BMInfo->bmiColors;
00954 
00955         for(INT32 x=0; x<=255; x++)
00956         {   
00957             Pal.rgbRed = (BYTE)(Start.rgbRed + (INT32)(((float)(End.rgbRed - Start.rgbRed) / 256.0) * x) & 255);
00958             Pal.rgbGreen = (BYTE)(Start.rgbGreen + (INT32)(((float)(End.rgbGreen - Start.rgbGreen) / 256.0) * x) & 255);
00959             Pal.rgbBlue = (BYTE)(Start.rgbBlue + (INT32)(((float)(End.rgbBlue - Start.rgbBlue) / 256.0) * x) & 255);
00960             Pal.rgbReserved = 0;
00961 
00962             DestPal[x] = Pal;
00963         }
00964 
00965         // Bit of a bodge here to get the background and foreground absolutely correct (with no roundings, etc).
00966         // The background of the library fonts is sometimes 253, 254 or 255, hence the three lines below.
00967         DestPal[0] = Start;
00968         DestPal[253] = End;
00969         DestPal[254] = End;
00970         DestPal[255] = End;
00971     }
00972 
00973     return TRUE;
00974 }
00975 #endif

Generated on Sat Nov 10 03:48:29 2007 for Camelot by  doxygen 1.4.4