dmose%mozilla.org 0efb7c174c updated xPL license boilerplate to v1.1, a=chofmann@netscape.com,r=endico@mozilla.org
git-svn-id: svn://10.0.0.236/trunk@52910 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 03:43:54 +00:00

293 lines
6.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
* wfFCache.cpp (wfFontCache.cpp)
*
* C++ implementation of a Font Cache. This does Font to Fmi
* mapping. Font <--> Fmi mapping is done by this.
*
* dp Suresh <dp@netscape.com>
*/
#include "nf.h"
#include "libfont.h"
#include "wfFCache.h"
//
// Uses : FontObject
#include "Mcf.h"
#include "f.h"
#include "Pcf.h"
static void free_font_store(wfList *object, void *item);
void
/*ARGSUSED*/
free_font_store(wfList *object, void *item)
{
struct font_store *ele = (struct font_store *) item;
nffmi_release(ele->fmi, NULL);
delete ele;
}
wfFontObjectCache::wfFontObjectCache()
: wfList(free_font_store)
{
}
wfFontObjectCache::~wfFontObjectCache()
{
}
// A match is a font object created for
// 1) the same rc type
// 2) the same fmi
// 3) the same accessor
// All fonts served by the native displayer can be shared
// irrespective of the accessor.
//
// So in the algorithm for a match of RcFmi2Font(), we will
// look for only sharable fonts.
//
struct nff *
wfFontObjectCache::RcFmi2Font(struct nfrc *rc, struct nffmi *fmi)
{
struct nff *f = NULL;
struct wfListElement *tmp = head;
for (; tmp; tmp = tmp->next)
{
struct font_store *ele = (struct font_store *) tmp->item;
cfImpl *oimpl = nff2cfImpl(ele->f);
FontObject *fob = (FontObject *)oimpl->object;
if (!fob->isShared())
{
continue;
}
jint f_rcMajorType = nff_GetRcMajorType(ele->f, NULL);
jint f_rcMinorType = nff_GetRcMinorType(ele->f, NULL);
if (nfrc_IsEquivalent(rc, f_rcMajorType, f_rcMinorType, NULL)) {
const char* eleFmiStr = nffmi_toString(ele->fmi, NULL);
const char* fmiStr = nffmi_toString(fmi, NULL);
if (eleFmiStr && fmiStr && !strcmp(eleFmiStr, fmiStr)) {
f = ele->f;
nff_addRef(f, NULL);
break;
}
}
}
return f;
}
#ifdef NOT_USED_ANYWHERE
struct nffmi *
wfFontObjectCache::Font2Fmi(struct nff *f)
{
struct nffmi *fmi = NULL;
struct wfListElement *tmp = head;
for (; tmp; tmp = tmp->next)
{
struct font_store *ele = (struct font_store *) tmp->item;
if (ele->f == f)
{
fmi = ele->fmi;
nffmi_addRef(fmi, NULL);
break;
}
}
return fmi;
}
#endif /* NOT_USED_ANYWHERE */
//
// Find the font corresponding to an rf
//
struct nff *
wfFontObjectCache::
Rf2Font(struct nfrf *rf)
{
struct nff *f = NULL;
struct wfListElement *tmp = head;
for (; tmp; tmp = tmp->next)
{
struct font_store *ele = (struct font_store *) tmp->item;
// We know that this Font object was created by us. So we can
// snoop into its implementation to call implementation specific
// methods.
cfImpl *oimpl = cf2cfImpl(ele->f);
FontObject *fob = (FontObject *)oimpl->object;
if (fob->isRfExist(rf))
{
f = ele->f;
nff_addRef((struct nff *)f, NULL);
break;
}
}
return f;
}
int
wfFontObjectCache::add(struct nffmi *fmi, struct nff *f)
{
struct font_store *ele = new font_store;
wfList::ERROR_CODE err;
int ret = 0;
if (!ele)
{
// No memory
return -1;
}
ele->fmi = fmi;
ele->f = f;
err = wfList::add(ele);
if (err != wfList::SUCCESS)
{
ret = -1;
}
else
{
if (fmi) nffmi_addRef(fmi, NULL);
//
// NOTE: The FontObject is refcounted by
// 1. The actual references of FontObjects by consumers
// 2. The fonthandle
// So even if all FontConsumers release a Font, the FontHandle
// that it contains will keep it from being destoyed. So we wont
// addRef the Font object. However, we need to be told when the
// FontObject is going away;
// hence, wfFontObjectCache::releaseFont()
//
//if (f) nff_addRef(f, NULL);
}
return (ret);
}
//
// This gets called when a font object is going away.
// Remove all references to the font object in our font object cache.
int
wfFontObjectCache::releaseFont(struct nff *f)
{
// The caller can specify either fmi or f
struct wfListElement *tmp;
wfList::ERROR_CODE err;
int ret = 0;
if (!f)
{
return (0);
}
tmp = head;
while (tmp)
{
struct font_store *ele = (struct font_store *) tmp->item;
// This could cause the element to be deleted. So move to the next
// element before proceeding with the delete.
tmp=tmp->next;
if (f == ele->f)
{
WF_TRACEMSG( ("NF: Removing font (0x%x) created for fmi (%s).", this,
nffmi_toString(ele->fmi, NULL)) );
err = wfList::remove(ele);
if (err != wfList::SUCCESS)
{
// Remove of this failed. Fail the overall remove.
ret += -1;
}
}
}
return (ret);
}
int
wfFontObjectCache::releaseRf(struct nfrf *rf)
{
#ifdef DEBUG
WF_TRACEMSG( ("NF: Deleting rf (0x%x).", rf) );
#endif /* DEBUG */
struct wfListElement *tmp = head;
int nrelease = 0;
while(tmp)
{
struct font_store *ele = (struct font_store *) tmp->item;
// We know that this Font object was created by us. So we can
// snoop into its implementation to call implementation specific
// methods.
cfImpl *oimpl = cf2cfImpl(ele->f);
FontObject *fob = (FontObject *)oimpl->object;
//
// WARNING: Before calling FontObject::releaseRf we need to get the
// next item in the list. This is because the FontObject could turn
// around and decide to remove itself from our list.
//
tmp = tmp->next;
int n = fob->releaseRf(rf);
if (n)
{
// Run the garbage collector since some rf was released. This
// could even cause the font object to be deleted.
if (!fob->GC())
{
struct nff *f_to_delete = (struct nff *) ele->f;
// Delete the FontObject. Deleting the FontObject will turn
// around and delete the element in the fontObjectCache list
// by calling FontObjectCache::releaseFont().
//
// So DONT REMOVE THE ELEMENT. It will be removed.
// wfList::remove(ele);
nff_addRef(f_to_delete, NULL);
nff_release(f_to_delete, NULL);
}
}
nrelease += n;
}
if (nrelease)
{
// Some font had this rf. It is not possbile then for the same rf
// exist with webfonts. Skip looking into the webfonts.
return(nrelease);
}
return (nrelease);
}