home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libfont / src / wfFCache.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.8 KB  |  289 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.  * wfFCache.cpp (wfFontCache.cpp)
  20.  *
  21.  * C++ implementation of a Font Cache. This does Font to Fmi
  22.  * mapping. Font <--> Fmi mapping is done by this.
  23.  *
  24.  * dp Suresh <dp@netscape.com>
  25.  */
  26.  
  27.  
  28. #include "nf.h"
  29. #include "libfont.h"
  30.  
  31. #include "wfFCache.h"
  32.  
  33. //
  34. // Uses : FontObject
  35. #include "Mcf.h"
  36. #include "f.h"
  37. #include "Pcf.h"
  38.  
  39. static void free_font_store(wfList *object, void *item);
  40.  
  41. void
  42. /*ARGSUSED*/
  43. free_font_store(wfList *object, void *item)
  44. {
  45.     struct font_store *ele = (struct font_store *) item;
  46.     nffmi_release(ele->fmi, NULL);
  47.     delete ele;
  48. }
  49.  
  50. wfFontObjectCache::wfFontObjectCache()
  51. : wfList(free_font_store)
  52. {
  53. }
  54.  
  55. wfFontObjectCache::~wfFontObjectCache()
  56. {
  57. }
  58.  
  59. // A match is a font object created for
  60. //    1) the same rc type
  61. //    2) the same fmi
  62. //    3) the same accessor
  63. // All fonts served by the native displayer can be shared
  64. // irrespective of the accessor.
  65. //
  66. // So in the algorithm for a match of RcFmi2Font(), we will
  67. // look for only sharable fonts.
  68. //
  69. struct nff *
  70. wfFontObjectCache::RcFmi2Font(struct nfrc *rc, struct nffmi *fmi)
  71. {
  72.     struct nff *f = NULL;
  73.     struct wfListElement *tmp = head;
  74.     for (; tmp; tmp = tmp->next)
  75.       {
  76.         struct font_store *ele = (struct font_store *) tmp->item;
  77.  
  78.         cfImpl *oimpl = nff2cfImpl(ele->f);
  79.         FontObject *fob = (FontObject *)oimpl->object;
  80.         if (!fob->isShared())
  81.         {
  82.             continue;
  83.         }
  84.         
  85.         jint f_rcMajorType = nff_GetRcMajorType(ele->f, NULL);
  86.         jint f_rcMinorType = nff_GetRcMinorType(ele->f, NULL);
  87.         if (nfrc_IsEquivalent(rc, f_rcMajorType, f_rcMinorType, NULL)) {
  88.             const char* eleFmiStr = nffmi_toString(ele->fmi, NULL);
  89.             const char* fmiStr = nffmi_toString(fmi, NULL);
  90.             if (eleFmiStr && fmiStr && !strcmp(eleFmiStr, fmiStr)) {
  91.                 f = ele->f;
  92.                 nff_addRef(f, NULL);
  93.                 break;
  94.             }
  95.         }
  96.       }
  97.     return f;
  98. }
  99.  
  100. #ifdef NOT_USED_ANYWHERE
  101. struct nffmi *
  102. wfFontObjectCache::Font2Fmi(struct nff *f)
  103. {
  104.     struct nffmi *fmi = NULL;
  105.     struct wfListElement *tmp = head;
  106.     for (; tmp; tmp = tmp->next)
  107.       {
  108.         struct font_store *ele = (struct font_store *) tmp->item;
  109.         if (ele->f == f)
  110.           {
  111.             fmi = ele->fmi;
  112.             nffmi_addRef(fmi, NULL);
  113.             break;
  114.           }
  115.       }
  116.     return fmi;
  117. }
  118. #endif /* NOT_USED_ANYWHERE */
  119.  
  120. //
  121. // Find the font corresponding to an rf
  122. //
  123.  
  124. struct nff *
  125. wfFontObjectCache::
  126. Rf2Font(struct nfrf *rf)
  127. {
  128.     struct nff *f = NULL;
  129.     struct wfListElement *tmp = head;
  130.     for (; tmp; tmp = tmp->next)
  131.       {
  132.         struct font_store *ele = (struct font_store *) tmp->item;
  133.  
  134.         // We know that this Font object was created by us. So we can
  135.         // snoop into its implementation to call implementation specific
  136.         // methods.
  137.         cfImpl *oimpl = cf2cfImpl(ele->f);
  138.         FontObject *fob = (FontObject *)oimpl->object;
  139.         if (fob->isRfExist(rf))
  140.           {
  141.             f = ele->f;
  142.             nff_addRef((struct nff *)f, NULL);
  143.             break;
  144.           }
  145.       }
  146.     return f;
  147. }
  148.  
  149.  
  150. int
  151. wfFontObjectCache::add(struct nffmi *fmi, struct nff *f)
  152. {
  153.     struct font_store *ele = new font_store;
  154.     wfList::ERROR_CODE err;
  155.     int ret = 0;
  156.  
  157.     if (!ele)
  158.       {
  159.         // No memory
  160.         return -1;
  161.       }
  162.     ele->fmi = fmi;
  163.     ele->f = f;
  164.  
  165.     err = wfList::add(ele);
  166.  
  167.     if (err != wfList::SUCCESS)
  168.       {
  169.         ret = -1;
  170.       }
  171.     else
  172.       {
  173.         if (fmi) nffmi_addRef(fmi, NULL);
  174.         //
  175.         // NOTE: The FontObject is refcounted by
  176.         //            1. The actual references of FontObjects by consumers
  177.         //            2. The fonthandle
  178.         //        So even if all FontConsumers release a Font, the FontHandle
  179.         //        that it contains will keep it from being destoyed. So we wont
  180.         //        addRef the Font object. However, we need to be told when the
  181.         //        FontObject is going away;
  182.         //        hence, wfFontObjectCache::releaseFont()
  183.         //
  184.         //if (f) nff_addRef(f, NULL);
  185.       }
  186.     return (ret);
  187. }
  188.  
  189.  
  190. //
  191. // This gets called when a font object is going away.
  192. // Remove all references to the font object in our font object cache.
  193. int
  194. wfFontObjectCache::releaseFont(struct nff *f)
  195. {
  196.     // The caller can specify either fmi or f
  197.     struct wfListElement *tmp;
  198.  
  199.     wfList::ERROR_CODE err;
  200.     int ret = 0;
  201.  
  202.     if (!f)
  203.     {
  204.         return (0);
  205.     }
  206.  
  207.     tmp = head;
  208.     while (tmp)
  209.     {
  210.         struct font_store *ele = (struct font_store *) tmp->item;
  211.         
  212.         // This could cause the element to be deleted. So move to the next
  213.         // element before proceeding with the delete.
  214.         tmp=tmp->next;
  215.         
  216.         if (f == ele->f)
  217.         {
  218.             WF_TRACEMSG( ("NF: Removing font (0x%x) created for fmi (%s).", this,
  219.                 nffmi_toString(ele->fmi, NULL)) );
  220.             err = wfList::remove(ele);
  221.             if (err != wfList::SUCCESS)
  222.             {
  223.                 // Remove of this failed. Fail the overall remove.
  224.                 ret += -1;
  225.             }
  226.         }
  227.     }
  228.  
  229.     return (ret);
  230. }
  231.  
  232.  
  233. int
  234. wfFontObjectCache::releaseRf(struct nfrf *rf)
  235. {
  236. #ifdef DEBUG
  237.     WF_TRACEMSG( ("NF: Deleting rf (0x%x).", rf) );
  238. #endif /* DEBUG */
  239.  
  240.     struct wfListElement *tmp = head;
  241.     int nrelease = 0;
  242.     while(tmp)
  243.     {
  244.         struct font_store *ele = (struct font_store *) tmp->item;
  245.  
  246.         // We know that this Font object was created by us. So we can
  247.         // snoop into its implementation to call implementation specific
  248.         // methods.
  249.         cfImpl *oimpl = cf2cfImpl(ele->f);
  250.         FontObject *fob = (FontObject *)oimpl->object;
  251.  
  252.         //
  253.         // WARNING: Before calling FontObject::releaseRf we need to get the
  254.         // next item in the list. This is because the FontObject could turn
  255.         // around and decide to remove itself from our list.
  256.         //
  257.         tmp = tmp->next;
  258.         int n = fob->releaseRf(rf);
  259.         if (n)
  260.         {
  261.             // Run the garbage collector since some rf was released. This
  262.             // could even cause the font object to be deleted.
  263.             if (!fob->GC())
  264.             {
  265.                 struct nff *f_to_delete = (struct nff *) ele->f;
  266.  
  267.                 // Delete the FontObject. Deleting the FontObject will turn
  268.                 // around and delete the element in the fontObjectCache list
  269.                 // by calling FontObjectCache::releaseFont().
  270.                 //
  271.                 // So DONT REMOVE THE ELEMENT. It will be removed.
  272.                 // wfList::remove(ele);
  273.  
  274.                 nff_addRef(f_to_delete, NULL);
  275.                 nff_release(f_to_delete, NULL);
  276.             }
  277.         }
  278.         nrelease += n;
  279.     }
  280.  
  281.     if (nrelease)
  282.     {
  283.         // Some font had this rf. It is not possbile then for the same rf
  284.         // exist with webfonts. Skip looking into the webfonts.
  285.         return(nrelease);
  286.     }
  287.     return (nrelease);
  288. }
  289.