Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
DrawTextCompress.c
/* |
File: DrawTextCompress.c |
Contains: |
Written by: Mark Krueger |
Copyright: Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/29/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <Types.h> |
#include <Memory.h> |
#include <ImageCompression.h> |
#include <QuickDraw.h> |
#include "DrawTextCodec.h" |
short |
CalcError(register char *src,short rowBytes,short index,register char *table); |
long |
Compress(char *baseAddr,short rowBytes,char *pBaseAddr,short pRowBytes, |
short bwidth,short bheight,long spatialQ,long temporalQ,char *dataPtr, |
Fixed *similarityP,SharedGlobals *sGlob); |
void InitCharTab(SharedGlobals *sGlob,ComponentInstance self); |
void MakeSkipTable(SharedGlobals *sGlob); |
/*********************** |
Compress bheight strips ( of bwidth blocks ) of pixels using the given table |
of char values. |
Source must be 1-bit/pixel. |
Should be called in 32-bit mmu mode, since we access pixels directly. |
***********************/ |
long |
Compress(char *baseAddr,short rowBytes,char *pBaseAddr,short pRowBytes, |
short bwidth,short bheight,long spatialQ,long temporalQ,char *dataPtr, |
Fixed *similarityP,SharedGlobals *sGlob) |
{ |
#pragma unused(pBaseAddr,pRowBytes,temporalQ) |
char *dataStart = dataPtr; |
char *bp; |
register short i; |
short x,y; |
short min = 1000,minIndex,e; |
char *charTab = sGlob->table; |
short startIndex = ' ',endIndex = 'z'; |
/* |
limit search based on requested quality level. |
*/ |
if ( spatialQ <= codecLowQuality ) { |
startIndex = ' '; |
endIndex = '9'; |
} |
else if ( spatialQ <= codecNormalQuality ) { |
startIndex = ' '; |
endIndex = 'z'; |
} else { |
startIndex = 0; |
endIndex = 255; |
} |
/* |
compress the strips |
*/ |
for ( y=0; y < bheight; y++ ) { |
bp = baseAddr; |
for (x=0; x < bwidth; x++) { |
min = 1000; |
/* find the best character for this block */ |
for (i=startIndex; i <= endIndex; i++) { |
if ( (e=CalcError(bp,rowBytes,i,charTab)) < min ) { |
min = e; |
minIndex = i; |
} |
if ( min == 0 ) |
break; |
} |
*dataPtr++ = minIndex; // write char as compressed data |
bp++; |
} |
baseAddr += rowBytes * FONT_HEIGHT; // bump to next strip |
} |
if ( similarityP ) // if we did similarity... |
*similarityP = 0; |
return(dataPtr - dataStart); |
} |
/************************ |
Calculate and return the number of pixels that dont match between the given block of |
1-bit pixels and the equivcalent indexed block in the table |
************************/ |
short |
CalcError(register char *src,short rowBytes,short index,register char *table) |
{ |
short err = 0; |
short i,j; |
register signed char d; |
table += index; |
for ( i=FONT_HEIGHT; i-- ; ) { |
d = *src ^ *table; |
if ( d != 0 ) { |
if ( d == 0xff ) |
err += 8; |
else { |
for ( j =FONT_WIDTH; j--; ) { |
if ( d < 0 ) |
err++; |
d <<= 1; |
} |
} |
} |
table += (256 * FONT_WIDTH) / 8; |
src += rowBytes; |
} |
return(err); |
} |
/************************ |
Build a bitmap table of the characters in the font. Keep as shared data. |
************************/ |
void InitCharTab(SharedGlobals *sGlob,ComponentInstance self) |
{ |
CGrafPtr savePort; |
GDHandle saveGD; |
short x; |
Rect rect; |
GWorldPtr gw; |
THz saveZone; |
Boolean inAppHeap; |
/* |
figure out which zone to use, based on where we are loaded. |
*/ |
saveZone = GetZone(); |
inAppHeap = ( GetComponentInstanceA5(self) != 0 ); |
if ( !inAppHeap ) |
SetZone(SystemZone()); |
sGlob->tableWorld = nil; |
sGlob->table = nil; |
GetGWorld(&savePort,&saveGD); |
SetRect(&rect,0,0,256*FONT_WIDTH,FONT_HEIGHT); |
if ( NewGWorld(&gw,1,&rect,nil,nil,0) == 0 ) { |
(*gw->portPixMap)->rowBytes = 0x8000 | (256 * FONT_WIDTH) / 8; |
SetGWorld(gw,nil); |
TextSize(FONT_SIZE); |
TextFont(FONT_ID); |
EraseRect(&rect); |
ClipRect(&rect); |
for (x=0; x < 256; x++) { |
MoveTo(x*FONT_WIDTH,BASE_LINE); |
DrawChar(x); |
} |
SetGWorld(savePort,saveGD); |
LockPixels(gw->portPixMap); |
sGlob->tableWorld = gw; |
sGlob->table = GetPixBaseAddr(gw->portPixMap); |
} |
SetZone(saveZone); |
} |
/************************ |
Figure duplicate font chars. not used. |
************************/ |
void MakeSkipTable(SharedGlobals *sGlob) |
{ |
short i,x; |
char *charTab = sGlob->table; |
for (i=0; i < 256; i++) |
sGlob->skipTable[i] = 0; |
for (i=0; i < 256; i++) { |
char *icp = charTab + i * FONT_WIDTH; |
if ( !sGlob->skipTable[i] ) { |
for (x=i+1; x < 256; x++) { |
if ( CalcError(icp,(256 * FONT_WIDTH) / 8,x,charTab) == 0) |
sGlob->skipTable[x] = 1; |
} |
} |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14