ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

glyph.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS win32 subsystem
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * PURPOSE:         GDI font driver for bitmap fonts
00005  * PROGRAMMER:      Timo Kreuzer (timo.kreuzer@reactos.org)
00006  */
00007 
00008 #include "bmfd.h"
00009 
00010 ULONG
00011 FORCEINLINE
00012 _ReadPixel(
00013     CHAR* pjBits,
00014     ULONG x,
00015     ULONG y,
00016     ULONG ulHeight)
00017 {
00018     CHAR j;
00019     j = pjBits[(x/8) * ulHeight + y];
00020     return (j >> (~x & 0x7)) & 1;
00021 }
00022 
00023 
00024 VOID
00025 FORCEINLINE
00026 _WritePixel(
00027     CHAR* pjBits,
00028     ULONG x,
00029     ULONG y,
00030     ULONG cjRow,
00031     ULONG color)
00032 {
00033     pjBits += y * cjRow;
00034     pjBits += x / 8;
00035     *pjBits |= color << (~x & 0x7);
00036 }
00037 
00038 
00039 PBMFD_FONT
00040 BmfdGetFontInstance(
00041     FONTOBJ *pfo,
00042     PBMFD_FACE pface)
00043 {
00044     PBMFD_FONT pfont = pfo->pvProducer;
00045     XFORMOBJ *pxo;
00046     FLOATOBJ_XFORM xfo;
00047 
00048     if (!pfont)
00049     {
00050         /* Allocate realization info */
00051         pfont = EngAllocMem(0, sizeof(BMFD_FONT), 0);
00052         if (!pfont)
00053         {
00054             return NULL;
00055         }
00056 
00057         pxo = FONTOBJ_pxoGetXform(pfo);
00058         XFORMOBJ_iGetFloatObjXform(pxo, &xfo);
00059 
00060         pfont->pfo = pfo;
00061         pfont->pface = pface;
00062         pfont->xScale = FLOATOBJ_GetLong(&xfo.eM11);
00063         pfont->yScale = FLOATOBJ_GetLong(&xfo.eM22);
00064         pfont->ulAngle = 0;
00065 
00066         /* Set the pvProducer member of the fontobj */
00067         pfo->pvProducer = pfont;
00068     }
00069 
00070     return pfont;
00071 }
00072 
00073 
00074 ULONG
00075 BmfdQueryGlyphAndBitmap(
00076     PBMFD_FONT pfont,
00077     HGLYPH hg,
00078     GLYPHDATA *pgd,
00079     GLYPHBITS *pgb,
00080     ULONG cjSize)
00081 {
00082     PBMFD_FACE pface = pfont->pface;
00083     PGLYPHENTRY pge = (PGLYPHENTRY)(pface->pCharTable + hg);
00084     ULONG xSrc, ySrc, cxSrc, cySrc;
00085     ULONG xDst, yDst, cxDst, cyDst;
00086     ULONG xScale, yScale;
00087     ULONG ulGlyphOffset, cjDstRow, color;
00088     PVOID pvSrc0, pvDst0;
00089 
00090     if (!pge)
00091     {
00092         DbgPrint("no glyph handle given!\n");
00093         return FD_ERROR;
00094     }
00095 
00096     /* Get the bitmap offset depending on file version */
00097     if (pface->ulVersion >= 0x300)
00098     {
00099         cxSrc = GETVAL(pge->ge20.geWidth);
00100         ulGlyphOffset = GETVAL(pge->ge30.geOffset);
00101     }
00102     else
00103     {
00104         cxSrc = GETVAL(pge->ge30.geWidth);
00105         ulGlyphOffset = GETVAL(pge->ge20.geOffset);
00106     }
00107     cySrc = pface->wPixHeight;
00108 
00109     /* Pointer to the bitmap bits */
00110     pvSrc0 = (PBYTE)pface->pFontInfo + ulGlyphOffset;
00111     pvDst0 = pgb->aj;
00112 
00113     xScale = pfont->xScale;
00114     yScale = pfont->yScale;
00115 
00116     /* Calculate extents of destination bitmap */
00117     if (pfont->ulAngle == 90 || pfont->ulAngle == 270)
00118     {
00119         cxDst = cySrc * xScale;
00120         cyDst = cxSrc * yScale;
00121     }
00122     else
00123     {
00124         cxDst = cxSrc * yScale;
00125         cyDst = cySrc * xScale;
00126     }
00127     cjDstRow = (cxDst + 7) / 8;
00128 
00129     if (pgd)
00130     {
00131         /* Fill GLYPHDATA structure */
00132         pgd->gdf.pgb = pgb;
00133         pgd->hg = hg;
00134         pgd->fxD = xScale * (pface->wA + cxDst + pface->wC) << 4;
00135         pgd->fxA = xScale * pface->wA << 4;
00136         pgd->fxAB = xScale * (pface->wA + cxDst) << 4;
00137         pgd->fxInkTop = yScale * pface->wAscent << 4;
00138         pgd->fxInkBottom = - yScale * (pface->wDescent << 4);
00139         pgd->rclInk.top = - yScale * pface->wAscent;
00140         pgd->rclInk.bottom = yScale * pface->wDescent;
00141         pgd->rclInk.left = xScale * pface->wA;
00142         pgd->rclInk.right = pgd->rclInk.left + cxDst;
00143         pgd->ptqD.x.LowPart = 0;
00144         pgd->ptqD.x.HighPart = pgd->fxD;
00145         pgd->ptqD.y.LowPart = 0;
00146         pgd->ptqD.y.HighPart = 0;
00147     }
00148 
00149     if (pgb)
00150     {
00151         /* Verify that the buffer is big enough */
00152         if (cjSize < FIELD_OFFSET(GLYPHBITS, aj) + cyDst * cjDstRow)
00153         {
00154             DbgPrint("Buffer too small (%ld), %ld,%ld\n", 
00155                      cjSize, cxSrc, cySrc);
00156             return FD_ERROR;
00157         }
00158 
00159         /* Fill GLYPHBITS structure */
00160         pgb->ptlOrigin.x = yScale * pface->wA;
00161         pgb->ptlOrigin.y = - yScale * pface->wAscent;
00162         pgb->sizlBitmap.cx = cxDst;
00163         pgb->sizlBitmap.cy = cyDst;
00164 
00165         /* Erase destination surface */
00166         memset(pvDst0, 0, cyDst * cjDstRow);
00167 
00168         switch (pfont->ulAngle)
00169         {
00170             case 90:
00171                 /* Copy pixels */
00172                 for (yDst = 0; yDst < cyDst ; yDst++)
00173                 {
00174                     xSrc = yDst / yScale;
00175                     for (xDst = 0; xDst < cxDst; xDst++)
00176                     {
00177                         ySrc = (cxDst - xDst) / xScale;
00178                         color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
00179                         _WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
00180                     }
00181                 }
00182                 break;
00183 
00184             case 180:
00185                 for (yDst = 0; yDst < cyDst ; yDst++)
00186                 {
00187                     ySrc = (cyDst - yDst) / yScale;
00188                     for (xDst = 0; xDst < cxDst; xDst++)
00189                     {
00190                         xSrc = (cxDst - xDst) / xScale;
00191                         color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
00192                         _WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
00193                     }
00194                 }
00195                 break;
00196 
00197             case 270:
00198                 for (yDst = 0; yDst < cyDst ; yDst++)
00199                 {
00200                     xSrc = (cyDst - yDst) / yScale;
00201                     for (xDst = 0; xDst < cxDst; xDst++)
00202                     {
00203                         ySrc = xDst / xScale;
00204                         color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
00205                         _WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
00206                     }
00207                 }
00208                 break;
00209 
00210             case 0:
00211             default:
00212                 for (yDst = 0; yDst < cyDst ; yDst++)
00213                 {
00214                     ySrc = yDst / yScale;
00215                     for (xDst = 0; xDst < cxDst; xDst++)
00216                     {
00217                         xSrc = xDst / xScale;
00218                         color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
00219                         _WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
00220                     }
00221                 }
00222         }
00223     }
00224 
00225     /* Return the size of the GLYPHBITS structure */
00226     return FIELD_OFFSET(GLYPHBITS, aj) + cyDst * cjDstRow;
00227 }
00228 
00229 ULONG
00230 BmfdQueryMaxExtents(
00231     PBMFD_FONT pfont,
00232     PFD_DEVICEMETRICS pfddm,
00233     ULONG cjSize)
00234 {
00235     ULONG cjMaxWidth, cjMaxBitmapSize;
00236     PFONTINFO16 pFontInfo;
00237     ULONG xScale, yScale;
00238 
00239     if (pfddm)
00240     {
00241         if (cjSize < sizeof(FD_DEVICEMETRICS))
00242         {
00243             /* Not enough space, fail */
00244             return FD_ERROR;
00245         }
00246 
00247         pFontInfo = pfont->pface->pFontInfo;
00248         
00249         xScale = pfont->xScale;
00250         yScale = pfont->yScale;
00251 
00252         /* Fill FD_DEVICEMETRICS */
00253         pfddm->flRealizedType = FDM_MASK;
00254         pfddm->pteBase.x = FLOATL_1;
00255         pfddm->pteBase.y = 0;
00256         pfddm->pteSide.x = 0;
00257         pfddm->pteSide.y = FLOATL_1;
00258         pfddm->ptlUnderline1.x = 0;
00259         pfddm->ptlUnderline1.y = 1;
00260         pfddm->ptlStrikeout.x = 0;
00261         pfddm->ptlStrikeout.y = -4;
00262         pfddm->ptlULThickness.x = 0;
00263         pfddm->ptlULThickness.y = 1;
00264         pfddm->ptlSOThickness.x = 0;
00265         pfddm->ptlSOThickness.y = 1;
00266         pfddm->lMinA = 0;
00267         pfddm->lMinC = 0;
00268         pfddm->lMinD = 0;
00269 
00270         if (pfont->ulAngle == 90 || pfont->ulAngle == 270)
00271         {
00272             pfddm->cxMax = xScale * GETVAL(pFontInfo->dfPixHeight);
00273             pfddm->cyMax = yScale * GETVAL(pFontInfo->dfMaxWidth);
00274             pfddm->fxMaxAscender = yScale * GETVAL(pFontInfo->dfAscent) << 4;
00275             pfddm->fxMaxDescender = (pfddm->cyMax << 4) - pfddm->fxMaxAscender;
00276         }
00277         else
00278         {
00279             pfddm->cxMax = xScale * GETVAL(pFontInfo->dfMaxWidth);
00280             pfddm->cyMax = yScale * GETVAL(pFontInfo->dfPixHeight);
00281             pfddm->fxMaxAscender = yScale * GETVAL(pFontInfo->dfAscent) << 4;
00282             pfddm->fxMaxDescender = (pfddm->cyMax << 4) - pfddm->fxMaxAscender;
00283         }
00284 
00285         pfddm->lD = pfddm->cxMax;
00286 
00287         /* Calculate Width in bytes */
00288         cjMaxWidth = ((pfddm->cxMax + 7) >> 3);
00289 
00290         /* Calculate size of the bitmap, rounded to DWORDs */
00291         cjMaxBitmapSize = ((cjMaxWidth * pfddm->cyMax) + 3) & ~3;
00292 
00293         /* cjGlyphMax is the full size of the GLYPHBITS structure */
00294         pfddm->cjGlyphMax = FIELD_OFFSET(GLYPHBITS, aj) + cjMaxBitmapSize;
00295 
00296         /* NOTE: fdxQuantized and NonLinear... stay unchanged */
00297     }
00298 
00299     /* Return the size of the structure */
00300     return sizeof(FD_DEVICEMETRICS);
00301 }
00302 
00303 
00306 PFD_GLYPHATTR
00307 APIENTRY
00308 BmfdQueryGlyphAttrs(
00309     FONTOBJ *pfo,
00310     ULONG iMode)
00311 {
00312     DbgPrint("BmfdQueryGlyphAttrs()\n");
00313     /* We don't support FO_ATTR_MODE_ROTATE */
00314     return NULL;
00315 }
00316 
00317 LONG
00318 APIENTRY
00319 BmfdQueryFontData(
00320     DHPDEV dhpdev,
00321     FONTOBJ *pfo,
00322     ULONG iMode,
00323     HGLYPH hg,
00324     OUT GLYPHDATA *pgd,
00325     PVOID pv,
00326     ULONG cjSize)
00327 {
00328     PBMFD_FILE pfile = (PBMFD_FILE)pfo->iFile;
00329     PBMFD_FACE pface = &pfile->aface[pfo->iFace - 1];
00330     PBMFD_FONT pfont= BmfdGetFontInstance(pfo, pface);
00331 
00332     DbgPrint("BmfdQueryFontData(pfo=%p, iMode=%ld, hg=%p, pgd=%p, pv=%p, cjSize=%ld)\n", 
00333              pfo, iMode, hg, pgd, pv, cjSize);
00334 //    __debugbreak();
00335 
00336     switch (iMode)
00337     {
00338         case QFD_GLYPHANDBITMAP: /* 1 */
00339             return BmfdQueryGlyphAndBitmap(pfont, hg, pgd, pv, cjSize);
00340 
00341         case QFD_MAXEXTENTS: /* 3 */
00342             return BmfdQueryMaxExtents(pfont, pv, cjSize);
00343             
00344             /* we support nothing else */
00345         default:
00346             return FD_ERROR;
00347 
00348     }
00349 
00350     return FD_ERROR;
00351 }

Generated on Sun May 27 2012 04:38:10 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.