home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libfont / producers / win / src / winrf.cpp < prev   
Encoding:
C/C++ Source or Header  |  1998-04-08  |  16.4 KB  |  573 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*
  19.  * Implements the Native windows RenderableFont
  20.  */
  21.  
  22. #include "Pwinrf.h"
  23.  
  24. #include "nf.h"
  25. #include "Mnfrc.h"
  26. #include "Mnffbp.h"
  27.  
  28. #include "coremem.h"
  29.  
  30. // todo: get rid of this global!!
  31. extern struct nffbp    *global_pBrokerObj;
  32.  
  33. /****************************************************************************
  34.  *                 Implementation of common interface methods
  35.  ****************************************************************************/
  36.  
  37. #ifdef OVERRIDE_winrf_getInterface
  38. #include "Mnfrf.h"
  39. #ifdef __cplusplus
  40. extern "C"
  41. #endif
  42. JMC_PUBLIC_API(void*)
  43. _winrf_getInterface(struct winrf* self, jint op, const JMCInterfaceID* iid, JMCException* *exc)
  44. {
  45.     if (memcmp(iid, &nfrf_ID, sizeof(JMCInterfaceID)) == 0)
  46.         return winrfImpl2winrf(winrf2winrfImpl(self));
  47.     return _winrf_getBackwardCompatibleInterface(self, iid, exc);
  48. }
  49. #endif /* OVERRIDE_winrf_getInterface */
  50.  
  51. #ifdef __cplusplus
  52. extern "C"
  53. #endif
  54. JMC_PUBLIC_API(void*)
  55. _winrf_getBackwardCompatibleInterface(struct winrf* self,
  56.                                     const JMCInterfaceID* iid,
  57.                                     struct JMCException* *exceptionThrown)
  58. {
  59.     return (NULL);
  60. }
  61.  
  62. #ifdef __cplusplus
  63. extern "C"
  64. #endif
  65. JMC_PUBLIC_API(void)
  66. _winrf_init(struct winrf* self, struct JMCException* *exceptionThrown)
  67. {
  68.     /* FONTDISPLAYER developers:
  69.      * This is supposed to do initialization that is required for the 
  70.      * font Displayer object.
  71.      */
  72.  
  73.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  74.  
  75.     if( pSampleRenderableFontData ) {
  76.         pSampleRenderableFontData->mRF_tmDescent        = 0;
  77.         pSampleRenderableFontData->mRF_tmMaxCharWidth    = 0;
  78.         pSampleRenderableFontData->mRF_tmAscent            = 0;
  79.         pSampleRenderableFontData->mRF_pointSize        = 0.0;
  80.         pSampleRenderableFontData->mRF_hFont            = NULL;
  81.     }
  82. }
  83.  
  84. #ifdef OVERRIDE_winrf_finalize
  85. #ifdef __cplusplus
  86. extern "C"
  87. #endif
  88. JMC_PUBLIC_API(void)
  89. _winrf_finalize(struct winrf* self, jint op, JMCException* *exception)
  90. {
  91.     /* FONTDISPLAYER developer:
  92.      * Free any private data for this object here.
  93.      */
  94.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  95.  
  96.     if( pSampleRenderableFontData ) {
  97.         if( pSampleRenderableFontData->mRF_hFont )
  98.             DeleteObject( pSampleRenderableFontData->mRF_hFont );
  99.         pSampleRenderableFontData->mRF_hFont = NULL;
  100.     }
  101.     
  102.     /*
  103.      * Tell the fontDisplayer that this renderable font is going away.
  104.      */
  105.     nffbp_RfDone(global_pBrokerObj, (struct nfrf *)self, NULL);
  106.  
  107.     /* Finally, free the memory for the object containter. */
  108.     XP_FREEIF(self);
  109. }
  110. #endif /* OVERRIDE_winrf_finalize */
  111.  
  112.  
  113. /****************************************************************************
  114.  *                 Implementation of Object specific methods
  115.  *
  116.  * FONTDISPLAYER developers:
  117.  * Implement your RenderableFont methods here.
  118.  ****************************************************************************/
  119.  
  120.  
  121. #ifdef __cplusplus
  122. extern "C"
  123. #endif
  124. JMC_PUBLIC_API(struct nffmi*)
  125. _winrf_GetMatchInfo(struct winrf* self, jint op,
  126.                   struct JMCException* *exceptionThrown)
  127. {
  128.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  129.     return NULL;
  130. }
  131.  
  132.  
  133. #ifdef __cplusplus
  134. extern "C"
  135. #endif
  136. JMC_PUBLIC_API(jdouble)
  137. _winrf_GetPointSize(struct winrf* self, jint op,
  138.                   struct JMCException* *exceptionThrown)
  139. {
  140.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  141.     return( pSampleRenderableFontData->mRF_pointSize );
  142.     //return (0);
  143. }
  144.  
  145.  
  146. #ifdef __cplusplus
  147. extern "C"
  148. #endif
  149. JMC_PUBLIC_API(jint)
  150. _winrf_GetMaxWidth(struct winrf* self, jint op,
  151.                  struct JMCException* *exceptionThrown)
  152. {
  153.     struct winrfImpl  *pSampleRenderableFontData;
  154.  
  155.     pSampleRenderableFontData = winrf2winrfImpl(self);
  156.  
  157.     // fetched and buffered in _cfp_GetRenderableFont()
  158.     return( pSampleRenderableFontData->mRF_tmMaxCharWidth );
  159.  
  160. }
  161.  
  162.  
  163. #ifdef __cplusplus
  164. extern "C"
  165. #endif
  166. JMC_PUBLIC_API(jint)
  167. _winrf_GetFontAscent(struct winrf* self, jint op,
  168.                   struct JMCException* *exceptionThrown)
  169. {
  170.     struct winrfImpl  *pSampleRenderableFontData;
  171.  
  172.     pSampleRenderableFontData = winrf2winrfImpl(self);
  173.  
  174.     // fetched and buffered in _cfp_GetRenderableFont()
  175.     return( pSampleRenderableFontData->mRF_tmAscent );
  176. }
  177.  
  178.  
  179. #ifdef __cplusplus
  180. extern "C"
  181. #endif
  182. JMC_PUBLIC_API(jint)
  183. _winrf_GetFontDescent(struct winrf* self, jint op,
  184.                    struct JMCException* *exceptionThrown)
  185. {
  186.     struct winrfImpl  *pSampleRenderableFontData;
  187.     pSampleRenderableFontData = winrf2winrfImpl(self);
  188.  
  189.     // fetched and buffered in _cfp_GetRenderableFont()
  190.     return( pSampleRenderableFontData->mRF_tmDescent );
  191.  
  192. }
  193.  
  194.  
  195. #ifdef __cplusplus
  196. extern "C"
  197. #endif
  198. JMC_PUBLIC_API(jint)
  199. _winrf_GetMaxLeftBearing(struct winrf* self, jint op,
  200.                        struct JMCException* *exceptionThrown)
  201. {
  202.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  203.     return (0);
  204. }
  205.  
  206.  
  207. #ifdef __cplusplus
  208. extern "C"
  209. #endif
  210. JMC_PUBLIC_API(jint)
  211. _winrf_GetMaxRightBearing(struct winrf* self, jint op,
  212.                         struct JMCException* *exceptionThrown)
  213. {
  214.     struct winrfImpl  *pSampleRenderableFontData;
  215.  
  216.     pSampleRenderableFontData = winrf2winrfImpl(self);
  217.  
  218.  
  219.     return (0);
  220. }
  221.  
  222.  
  223. #ifdef __cplusplus
  224. extern "C"
  225. #endif
  226. JMC_PUBLIC_API(void)
  227. _winrf_SetTransformMatrix(struct winrf* self, jint op,
  228.                         void ** matrix, jsize matrix_length,
  229.                         struct JMCException* *exceptionThrown)
  230. {
  231.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  232.     return;
  233. }
  234.  
  235.  
  236. #ifdef __cplusplus
  237. extern "C"
  238. #endif
  239. JMC_PUBLIC_API(void *)
  240. _winrf_GetTransformMatrix(struct winrf* self, jint op,
  241.                         struct JMCException* *exceptionThrown)
  242. {
  243.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  244.     return NULL;
  245. }
  246.  
  247. #ifndef _WIN32
  248. static BOOL GetTextExtentExPoint(HDC hDC, LPCSTR cp, int len, 
  249.               int rightBoundary, LPINT charCountInRow, LPINT charPos, LPSIZE zzz )
  250. {                     
  251.   
  252.   DWORD dd;
  253.  
  254.   LPCSTR  lcp = cp;
  255.   int     nn,  xx  = 0;  
  256.   
  257.   for( nn = 0; nn < len && xx < rightBoundary ; nn++ )
  258.   {
  259.     dd = GetTextExtent( hDC,  lcp, 1);
  260.     charPos[ nn ] = xx   += LOWORD(dd); 
  261.     lcp++ ;
  262.     }
  263.   
  264.   *charCountInRow = nn;    
  265.   zzz->cx = xx;
  266.   zzz->cy = HIWORD(dd);    
  267.     return(TRUE);
  268. }              
  269. #endif
  270.  
  271. #ifdef __cplusplus
  272. extern "C"
  273. #endif
  274. JMC_PUBLIC_API(jint)
  275. _winrf_MeasureText(struct winrf* self, jint op, struct nfrc* rc,
  276.                  jint charSpacing, /* XXX Arthur needs to implement this - dp */
  277.                  jbyte* bytes, jsize nbytes,
  278.                  jint *charLocs, jsize charLocs_length,
  279.                  struct JMCException* *exceptionThrown)
  280. {
  281.     struct winrfImpl *pSampleRenderableFontData = winrf2winrfImpl(self);
  282.  
  283.     HDC     hDC;
  284.     // HFONT   hFont;
  285.     // HFONT   hOldFont;
  286.     jsize   bytesToMeasure;         //  unsigned long
  287.     SIZE    theSize;
  288.     BOOL    bb;
  289. #ifndef NO_PERFORMANCE_HACK
  290.     struct rc_data *DisplayRCData = NF_GetRCNativeData(rc);
  291. #else
  292.     struct rc_data  RenderingContextData;
  293. #endif /* NO_PERFORMANCE_HACK */
  294.     jint    nn;
  295.     int        ii;
  296.     int     temp_encoding   = pSampleRenderableFontData->mRF_encoding;
  297.     
  298.     // GetTextExtentExPoint uses int_array not long(jint)_array
  299.     int        nCharLoc[1024];        // must > charLocs_length
  300.  
  301.     if( charLocs_length > 1024 )
  302.         return(0);        // error
  303.  
  304. #ifndef NO_PERFORMANCE_HACK
  305.     hDC = (HDC) DisplayRCData->t.directRc.dc;
  306. #else
  307.     RenderingContextData = nfrc_GetPlatformData( rc, NULL/*exception*/ ); 
  308.     if( RenderingContextData.majorType != NF_RC_DIRECT )
  309.         return(-1);        // error
  310.     
  311.     // get the passed-in HDC, 
  312.     hDC     = (HDC) RenderingContextData.t.directRc.dc ;
  313. #endif /* NO_PERFORMANCE_HACK */
  314.  
  315.  
  316.     // todo compare saved HDC with passed-in HDC, they must be compitable.
  317.  
  318.     // Select font should have been done in prepareDraw().
  319.     // get the font we saved when create this rf.
  320.     // hFont   = pSampleRenderableFontData->mRF_hFont;
  321.     //load the font, and save the old fond
  322.     // hOldFont = SelectObject( hDC, hFont);
  323.  
  324.     if( charLocs == NULL ) {        // only get the whole lenght, not the array
  325. #ifdef WIN32
  326.         if( temp_encoding & encode_unicode ) {  //todo 
  327.             bb = ::GetTextExtentPoint32W(hDC, (const unsigned short *)bytes, nbytes/2, &theSize );
  328.         } else {
  329.             bb = GetTextExtentPoint32(hDC, bytes, nbytes, &theSize );
  330.         }
  331. #else
  332.         bb = GetTextExtentPoint(hDC, bytes, nbytes, &theSize );
  333. #endif
  334.         nn = bb ? theSize.cx : -1 ;
  335.  
  336.     } else {
  337.  
  338.         // get the minimum of the length
  339.         bytesToMeasure = nbytes;
  340.         if( bytesToMeasure > charLocs_length ) 
  341.             bytesToMeasure = charLocs_length;
  342.         
  343.         // GetTextExtentPoint for 16 bit
  344. // TOD multi byte
  345.         if( temp_encoding & encode_unicode ) {  
  346.             //todo 
  347.         } else {
  348.             bb = GetTextExtentExPoint( 
  349.                     hDC,                // the HDC with selected Font
  350.                     bytes,              // string to measure
  351.                     bytesToMeasure,     // number of bytes in string
  352.                     2048,               // max logical width for formated string, big enough to let the measuring go
  353.                     NULL,                // count of char fix in max logical width.
  354.                     nCharLoc,           // the result, width of sub-string for each chr position.
  355.                     &theSize            // not used
  356.             );
  357.         }
  358.  
  359.         nn = bb ? 0 : -1 ;
  360.  
  361.         // copy the int array to long(jint) array
  362.         for( ii=0; ii < (int)bytesToMeasure; ii++ ) {
  363.             charLocs[ii] = nCharLoc[ii];
  364.         }
  365.  
  366.     } 
  367.  
  368.  
  369.     // Select font should have been done in prepareDraw().
  370.     // put the old font back after drawtext.
  371.     //SelectObject( hDC, hOldFont);
  372.  
  373.     // return value is in charLocs
  374.     return ( nn );
  375. }
  376.  
  377. #ifdef __cplusplus
  378. extern "C"
  379. #endif
  380. JMC_PUBLIC_API(jint)
  381. _winrf_MeasureBoundingBox(struct winrf* self, jint op, struct nfrc* rc,
  382.                  jint charSpacing, /* XXX Arthur needs to implement this - dp */
  383.                  jbyte* bytes, jsize nbytes, struct nf_bounding_box *bboxp,
  384.                  struct JMCException* *exceptionThrown)
  385. {
  386.     /* XXX Arthur needs to look over this implementation - dp */
  387.     if (!bboxp)
  388.         return (-1);
  389.  
  390.     bboxp->ascent = nfrf_GetFontAscent(self, NULL);
  391.     bboxp->descent = nfrf_GetFontDescent(self, NULL);
  392.     bboxp->width = nfrf_MeasureText(self, rc, charSpacing, bytes, nbytes,
  393.         NULL, 0, NULL);
  394.     bboxp->lbearing = 0;
  395.     bboxp->rbearing = bboxp->width;
  396.  
  397.     return (0);
  398. }
  399.  
  400. #ifdef __cplusplus
  401. extern "C"
  402. #endif
  403. JMC_PUBLIC_API(jint)
  404. _winrf_DrawText(struct winrf* self, jint op, struct nfrc* rc,
  405.               jint x, jint y,
  406.               jint charSpacing, /* XXX Arthur needs to implement this - dp */
  407.               jbyte* bytes, jsize nbytes,
  408.               struct JMCException* *exceptionThrown)
  409. {
  410.     struct winrfImpl  *pSampleRenderableFontData;
  411. #ifndef NO_PERFORMANCE_HACK
  412.     struct rc_data *DisplayRCData = NF_GetRCNativeData(rc);
  413. #else
  414.     struct rc_data  RenderingContextData;
  415. #endif /* NO_PERFORMANCE_HACK */
  416.     HDC             hDC;
  417.     // HFONT           hFont;
  418.     //HFONT           hOldFont;
  419.     int                temp_encoding;
  420.  
  421.     // get a pointer to my implementation data of renderable font.
  422.     pSampleRenderableFontData = winrf2winrfImpl(self);
  423.     
  424.     // Get a pointer to platform specific RenderingContext data
  425.     // form passed-in rc. For Windows, it has a HDC.
  426. #ifndef NO_PERFORMANCE_HACK
  427.     hDC = (HDC) DisplayRCData->t.directRc.dc;
  428. #else
  429.     RenderingContextData = nfrc_GetPlatformData( rc, NULL/*exception*/ ); 
  430.     if( RenderingContextData.majorType != NF_RC_DIRECT )
  431.         return(1);
  432.     
  433.     // get the passed-in HDC for drawing text, it may have clip info.
  434.     hDC     = (HDC) RenderingContextData.t.directRc.dc ;
  435. #endif /* NO_PERFORMANCE_HACK */
  436.  
  437.     // There are 2 HDC's here. One is passed in, another is
  438.     // saved when this rf was created( pSampleRenderableFontData->mRF_hDC).
  439.     // todo: compare those 2 HDC's to make sure they are compitable.
  440.  
  441.     temp_encoding   = pSampleRenderableFontData->mRF_encoding;
  442.  
  443.     // Select font should have been done in prepareDraw().
  444.     // get the font we saved when create this rf.
  445.     // hFont   = pSampleRenderableFontData->mRF_hFont;
  446.     //load the font, and save the old fond
  447.     // hOldFont = SelectObject( hDC, hFont);
  448.  
  449. #ifdef WIN32
  450.     if( temp_encoding & encode_unicode ) {  //todo 
  451.         // Now just draw text through the passed-in DC, with my Font loaded.
  452.         TextOutW(hDC, x, y, (const unsigned short *)bytes, nbytes / 2);
  453.  
  454.         if( temp_encoding & encode_needDrawUnderline )
  455.         {
  456.             // Measure Text By Calling MeasureText
  457.             // Draw the Underline
  458.             SIZE    theSize;
  459.             int        baseLine = 0;    
  460.  
  461.             // must get the size to decide where to draw, and the thickness of underLine
  462.             if( TRUE == ::GetTextExtentPoint32W(hDC, (const unsigned short *)bytes, nbytes/2, &theSize ) ) {
  463.                 baseLine = y + theSize.cy - 1;        // at bottom of the box
  464.             }
  465.  
  466.             if( baseLine > 0 ) {
  467.                 
  468.                 // try to get a better underLine position.
  469.                 /* this doesn't work on win95, see bug #49585
  470.                 OUTLINETEXTMETRIC oltm;
  471.                 if( TRUE == ::GetOutlineTextMetrics(hDC, sizeof(OUTLINETEXTMETRIC), & oltm ) ) {
  472.                     baseLine = y + oltm.otmsUnderscorePosition;
  473.                 }
  474.                 */
  475.  
  476.                 //now draw it
  477.                 HPEN cpStrike = ::CreatePen(PS_SOLID, theSize.cy / 10, ::GetTextColor(hDC) );
  478.                 HPEN pOldPen = (HPEN)::SelectObject(hDC, cpStrike);
  479.                 ::MoveToEx(hDC, x, baseLine, NULL);
  480.                 ::LineTo(hDC, x+theSize.cx, baseLine);
  481.                 ::SelectObject(hDC, pOldPen);
  482.                 ::DeleteObject(cpStrike);
  483.             }
  484.         }
  485.  
  486.     } else {
  487.         // Now just draw text through the passed-in DC, with my Font loaded.
  488.         TextOut( hDC, x, y, bytes, nbytes);
  489.     }
  490. #else
  491.         TextOut( hDC, x, y, bytes, nbytes);
  492. #endif
  493.  
  494.     // Select font should have been done in prepareDraw().
  495.     // put the old font back after drawtext.
  496.     // SelectObject( hDC, hOldFont);
  497.     
  498.     return (0);
  499. }
  500.  
  501. #ifdef __cplusplus
  502. extern "C"
  503. #endif
  504. JMC_PUBLIC_API(jint)
  505. _winrf_PrepareDraw(struct winrf* self, jint op, struct nfrc *rc,
  506.                  struct JMCException* *exceptionThrown)
  507. {
  508.     struct winrfImpl  *pSampleRenderableFontData;
  509.     struct rc_data  RenderingContextData;
  510.     HDC             hDC;
  511.  
  512.     // get a pointer to my implementation data of renderable font.
  513.     pSampleRenderableFontData = winrf2winrfImpl(self);
  514.  
  515.     if( pSampleRenderableFontData->mRF_hFont == NULL )
  516.         return(1);
  517.  
  518.     // Get a pointer to platform specific RenderingContext data
  519.     // form passed-in rc. For Windows, it has a HDC.
  520.     RenderingContextData = nfrc_GetPlatformData( rc, NULL/*exception*/ ); 
  521.     if( RenderingContextData.majorType != NF_RC_DIRECT )
  522.         return(1);
  523.  
  524.     // get the passed-in HDC for drawing text, it may have clip info.
  525.     hDC     = (HDC) RenderingContextData.t.directRc.dc ;
  526.  
  527.     // get the font we saved when create this rf.
  528.     // load the font, and save the old fond
  529.     RenderingContextData.displayer_data = (void *) SelectObject( hDC, pSampleRenderableFontData->mRF_hFont);
  530.  
  531.     if( RenderingContextData.displayer_data == NULL )
  532.         return(1);
  533.  
  534.     return 0;
  535. }
  536.  
  537. #ifdef __cplusplus
  538. extern "C"
  539. #endif
  540. JMC_PUBLIC_API(jint)
  541. _winrf_EndDraw(struct winrf* self, jint op, struct nfrc *rc,
  542.              struct JMCException* *exceptionThrown)
  543. {
  544.     struct winrfImpl  *pSampleRenderableFontData;
  545.     struct rc_data  RenderingContextData;
  546.     HDC             hDC;
  547.  
  548.     // get a pointer to my implementation data of renderable font.
  549.     pSampleRenderableFontData = winrf2winrfImpl(self);
  550.  
  551.  
  552.     // Get a pointer to platform specific RenderingContext data
  553.     // form passed-in rc. For Windows, it has a HDC.
  554.     RenderingContextData = nfrc_GetPlatformData( rc, NULL/*exception*/ ); 
  555.     if( RenderingContextData.majorType != NF_RC_DIRECT )
  556.         return(1);
  557.  
  558.     // get the passed-in HDC for drawing text, it may have clip info.
  559.     hDC     = (HDC)RenderingContextData.t.directRc.dc ;
  560.     
  561.  
  562.     if( RenderingContextData.displayer_data == NULL ) {
  563.         SelectObject(hDC, GetStockObject(ANSI_FIXED_FONT));
  564.     } else {
  565.         // put the old font back after drawtext.
  566.         SelectObject( hDC, ( HFONT ) RenderingContextData.displayer_data );
  567.     }
  568.     
  569.     RenderingContextData.displayer_data = NULL;
  570.  
  571.     return 0;
  572. }
  573.