Tesseract
3.02
|
#include <math.h>
#include <stdio.h>
#include <assert.h>
#include "classify.h"
#include "const.h"
#include "emalloc.h"
#include "fontinfo.h"
#include "genericvector.h"
#include "globals.h"
#include "helpers.h"
#include "intproto.h"
#include "mfoutline.h"
#include "ndminx.h"
#include "picofeat.h"
#include "shapetable.h"
#include "svmnode.h"
Go to the source code of this file.
Classes | |
struct | FILL_SWITCH |
struct | TABLE_FILLER |
struct | FILL_SPEC |
Namespaces | |
namespace | tesseract |
Defines | |
#define | PROTO_PRUNER_SCALE (4.0) |
#define | INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE) |
#define | INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE) |
#define | INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE) |
#define | INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE) |
#define | INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE) |
#define | INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE) |
#define | INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
#define | INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
#define | INT_MIN_X 0 |
#define | INT_MIN_Y 0 |
#define | INT_MAX_X INT_CHAR_NORM_RANGE |
#define | INT_MAX_Y INT_CHAR_NORM_RANGE |
#define | HV_TOLERANCE (0.0025) |
#define | MAX_NUM_SWITCHES 3 |
#define | OLD_MAX_NUM_CONFIGS 32 |
#define | OLD_WERDS_PER_CONFIG_VEC |
#define | CircularIncrement(i, r) (((i) < (r) - 1)?((i)++):((i) = 0)) |
#define | MapParam(P, O, N) (floor (((P) + (O)) * (N))) |
#define | MAX_LEVEL 2 |
#define | XS X_SHIFT |
#define | YS Y_SHIFT |
#define | AS ANGLE_SHIFT |
#define | NB NUM_CP_BUCKETS |
Enumerations | |
enum | SWITCH_TYPE { StartSwitch, EndSwitch, LastSwitch } |
Functions | |
FLOAT32 | BucketStart (int Bucket, FLOAT32 Offset, int NumBuckets) |
FLOAT32 | BucketEnd (int Bucket, FLOAT32 Offset, int NumBuckets) |
void | DoFill (FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, register uinT32 ClassMask, register uinT32 ClassCount, register uinT32 WordIndex) |
BOOL8 | FillerDone (TABLE_FILLER *Filler) |
void | FillPPCircularBits (uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) |
void | FillPPLinearBits (uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) |
void | GetCPPadsForLevel (int Level, FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad) |
ScrollView::Color | GetMatchColorFor (FLOAT32 Evidence) |
void | GetNextFill (TABLE_FILLER *Filler, FILL_SPEC *Fill) |
void | InitTableFiller (FLOAT32 EndPad, FLOAT32 SidePad, FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER *Filler) |
void | RenderIntFeature (ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color) |
void | RenderIntProto (ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color) |
int | TruncateParam (FLOAT32 Param, int Min, int Max, char *Id) |
void | AddIntClass (INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) |
int | AddIntConfig (INT_CLASS Class) |
int | AddIntProto (INT_CLASS Class) |
void | AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates) |
void | AddProtoToProtoPruner (PROTO Proto, int ProtoId, INT_CLASS Class, bool debug) |
int | BucketFor (FLOAT32 Param, FLOAT32 Offset, int NumBuckets) |
int | CircBucketFor (FLOAT32 Param, FLOAT32 Offset, int NumBuckets) |
void | UpdateMatchDisplay () |
void | ConvertConfig (BIT_VECTOR Config, int ConfigId, INT_CLASS Class) |
void | DisplayIntFeature (const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence) |
void | DisplayIntProto (INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence) |
INT_CLASS | NewIntClass (int MaxNumProtos, int MaxNumConfigs) |
void | free_int_class (INT_CLASS int_class) |
INT_TEMPLATES | NewIntTemplates () |
void | free_int_templates (INT_TEMPLATES templates) |
void | tesseract::ClearFeatureSpaceWindow (NORM_METHOD norm_method, ScrollView *window) |
void | InitIntMatchWindowIfReqd () |
void | InitProtoDisplayWindowIfReqd () |
void | InitFeatureDisplayWindowIfReqd () |
ScrollView * | CreateFeatureSpaceWindow (const char *name, int xpos, int ypos) |
Variables | |
ScrollView * | IntMatchWindow = NULL |
ScrollView * | FeatureDisplayWindow = NULL |
ScrollView * | ProtoDisplayWindow = NULL |
int | classify_num_cp_levels = 3 |
double | classify_cp_angle_pad_loose = 45.0 |
double | classify_cp_angle_pad_medium = 20.0 |
double | classify_cp_angle_pad_tight = 10.0 |
double | classify_cp_end_pad_loose = 0.5 |
double | classify_cp_end_pad_medium = 0.5 |
double | classify_cp_end_pad_tight = 0.5 |
double | classify_cp_side_pad_loose = 2.5 |
double | classify_cp_side_pad_medium = 1.2 |
double | classify_cp_side_pad_tight = 0.6 |
double | classify_pp_angle_pad = 45.0 |
double | classify_pp_end_pad = 0.5 |
double | classify_pp_side_pad = 2.5 |
#define AS ANGLE_SHIFT |
#define CircularIncrement | ( | i, | |
r | |||
) | (((i) < (r) - 1)?((i)++):((i) = 0)) |
macro for performing circular increments of bucket indices
Definition at line 121 of file intproto.cpp.
#define HV_TOLERANCE (0.0025) |
define pad used to snap near horiz/vertical protos to horiz/vertical
Definition at line 70 of file intproto.cpp.
#define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE) |
Definition at line 56 of file intproto.cpp.
#define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE) |
Definition at line 58 of file intproto.cpp.
#define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE) |
Definition at line 55 of file intproto.cpp.
#define INT_MAX_X INT_CHAR_NORM_RANGE |
Definition at line 66 of file intproto.cpp.
#define INT_MAX_Y INT_CHAR_NORM_RANGE |
Definition at line 67 of file intproto.cpp.
#define INT_MIN_X 0 |
Definition at line 64 of file intproto.cpp.
#define INT_MIN_Y 0 |
Definition at line 65 of file intproto.cpp.
#define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE) |
Definition at line 60 of file intproto.cpp.
#define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE) |
Definition at line 57 of file intproto.cpp.
#define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
Definition at line 62 of file intproto.cpp.
#define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE) |
Definition at line 61 of file intproto.cpp.
#define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
Definition at line 63 of file intproto.cpp.
#define MapParam | ( | P, | |
O, | |||
N | |||
) | (floor (((P) + (O)) * (N))) |
macro for mapping floats to ints without bounds checking
Definition at line 124 of file intproto.cpp.
#define MAX_LEVEL 2 |
#define MAX_NUM_SWITCHES 3 |
Definition at line 75 of file intproto.cpp.
#define NB NUM_CP_BUCKETS |
#define OLD_MAX_NUM_CONFIGS 32 |
Definition at line 113 of file intproto.cpp.
#define OLD_WERDS_PER_CONFIG_VEC |
((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\ BITS_PER_WERD)
Definition at line 114 of file intproto.cpp.
#define PROTO_PRUNER_SCALE (4.0) |
Definition at line 53 of file intproto.cpp.
#define XS X_SHIFT |
#define YS Y_SHIFT |
enum SWITCH_TYPE |
Definition at line 72 of file intproto.cpp.
{ StartSwitch, EndSwitch, LastSwitch }
void AddIntClass | ( | INT_TEMPLATES | Templates, |
CLASS_ID | ClassId, | ||
INT_CLASS | Class | ||
) |
This routine adds a new class structure to a set of templates. Classes have to be added to Templates in the order of increasing ClassIds.
Templates | templates to add new class to |
ClassId | class id to associate new class with |
Class | class data structure to add to templates |
Globals: none
Definition at line 224 of file intproto.cpp.
{ int Pruner; assert (LegalClassId (ClassId)); if (ClassId != Templates->NumClasses) { fprintf(stderr, "Please make sure that classes are added to templates"); fprintf(stderr, " in increasing order of ClassIds\n"); exit(1); } ClassForClassId (Templates, ClassId) = Class; Templates->NumClasses++; if (Templates->NumClasses > MaxNumClassesIn (Templates)) { Pruner = Templates->NumClassPruners++; Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT; memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT)); } } /* AddIntClass */
int AddIntConfig | ( | INT_CLASS | Class | ) |
This routine returns the index of the next free config in Class.
Class | class to add new configuration to |
Globals: none
Definition at line 257 of file intproto.cpp.
{ int Index; assert(Class->NumConfigs < MAX_NUM_CONFIGS); Index = Class->NumConfigs++; Class->ConfigLengths[Index] = 0; return Index; } /* AddIntConfig */
int AddIntProto | ( | INT_CLASS | Class | ) |
This routine allocates the next free proto in Class and returns its index.
Class | class to add new proto to |
Globals: none
Definition at line 281 of file intproto.cpp.
{ int Index; int ProtoSetId; PROTO_SET ProtoSet; INT_PROTO Proto; register uinT32 *Word; if (Class->NumProtos >= MAX_NUM_PROTOS) return (NO_PROTO); Index = Class->NumProtos++; if (Class->NumProtos > MaxNumIntProtosIn(Class)) { ProtoSetId = Class->NumProtoSets++; ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT)); Class->ProtoSets[ProtoSetId] = ProtoSet; memset(ProtoSet, 0, sizeof(*ProtoSet)); /* reallocate space for the proto lengths and install in class */ Class->ProtoLengths = (uinT8 *)Erealloc(Class->ProtoLengths, MaxNumIntProtosIn(Class) * sizeof(uinT8)); memset(&Class->ProtoLengths[Index], 0, sizeof(*Class->ProtoLengths) * (MaxNumIntProtosIn(Class) - Index)); } /* initialize proto so its length is zero and it isn't in any configs */ Class->ProtoLengths[Index] = 0; Proto = ProtoForProtoId (Class, Index); for (Word = Proto->Configs; Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0); return (Index); } /* AddIntProto */
void AddProtoToClassPruner | ( | PROTO | Proto, |
CLASS_ID | ClassId, | ||
INT_TEMPLATES | Templates | ||
) |
Definition at line 320 of file intproto.cpp.
{ CLASS_PRUNER_STRUCT* Pruner; uinT32 ClassMask; uinT32 ClassCount; uinT32 WordIndex; int Level; FLOAT32 EndPad, SidePad, AnglePad; TABLE_FILLER TableFiller; FILL_SPEC FillSpec; Pruner = CPrunerFor (Templates, ClassId); WordIndex = CPrunerWordIndexFor (ClassId); ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassId); for (Level = classify_num_cp_levels - 1; Level >= 0; Level--) { GetCPPadsForLevel(Level, &EndPad, &SidePad, &AnglePad); ClassCount = CPrunerMaskFor (Level, ClassId); InitTableFiller(EndPad, SidePad, AnglePad, Proto, &TableFiller); while (!FillerDone (&TableFiller)) { GetNextFill(&TableFiller, &FillSpec); DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex); } } } /* AddProtoToClassPruner */
Definition at line 364 of file intproto.cpp.
{ /* ** Parameters: ** Proto floating-pt proto to be added to proto pruner ** ProtoId id of proto ** Class integer class that contains desired proto pruner ** Globals: none ** Operation: This routine updates the proto pruner lookup tables ** for Class to include a new proto identified by ProtoId ** and described by Proto. ** Return: none ** Exceptions: none ** History: Fri Feb 8 13:07:19 1991, DSJ, Created. */ FLOAT32 Angle, X, Y, Length; FLOAT32 Pad; int Index; PROTO_SET ProtoSet; if (ProtoId >= Class->NumProtos) cprintf("AddProtoToProtoPruner:assert failed: %d < %d", ProtoId, Class->NumProtos); assert(ProtoId < Class->NumProtos); Index = IndexForProto (ProtoId); ProtoSet = Class->ProtoSets[SetForProto (ProtoId)]; Angle = Proto->Angle; #ifndef _WIN32 assert(!isnan(Angle)); #endif FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index, Angle + ANGLE_SHIFT, classify_pp_angle_pad / 360.0, debug); Angle *= 2.0 * PI; Length = Proto->Length; X = Proto->X + X_SHIFT; Pad = MAX (fabs (cos (Angle)) * (Length / 2.0 + classify_pp_end_pad * GetPicoFeatureLength ()), fabs (sin (Angle)) * (classify_pp_side_pad * GetPicoFeatureLength ())); FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad, debug); Y = Proto->Y + Y_SHIFT; Pad = MAX (fabs (sin (Angle)) * (Length / 2.0 + classify_pp_end_pad * GetPicoFeatureLength ()), fabs (cos (Angle)) * (classify_pp_side_pad * GetPicoFeatureLength ())); FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_Y], Index, Y, Pad, debug); } /* AddProtoToProtoPruner */
Definition at line 1254 of file intproto.cpp.
{ /* ** Parameters: ** Bucket bucket whose end is to be computed ** Offset offset used to map params to buckets ** NumBuckets total number of buckets ** Globals: none ** Operation: This routine returns the parameter value which ** corresponds to the end of the specified bucket. ** The bucket number should have been generated using the ** BucketFor() function with parameters Offset and NumBuckets. ** Return: Param value corresponding to end position of Bucket. ** Exceptions: none ** History: Thu Feb 14 13:24:33 1991, DSJ, Created. */ return (((FLOAT32) (Bucket + 1) / NumBuckets) - Offset); } /* BucketEnd */
Definition at line 425 of file intproto.cpp.
{ /* ** Parameters: ** Param parameter value to map into a bucket number ** Offset amount to shift param before mapping it ** NumBuckets number of buckets to map param into ** Globals: none ** Operation: This routine maps a parameter value into a bucket between ** 0 and NumBuckets-1. Offset is added to the parameter ** before mapping it. Values which map to buckets outside ** the range are truncated to fit within the range. Mapping ** is done by truncating rather than rounding. ** Return: Bucket number corresponding to Param + Offset. ** Exceptions: none ** History: Thu Feb 14 13:24:33 1991, DSJ, Created. */ return ClipToRange(static_cast<int>(MapParam(Param, Offset, NumBuckets)), 0, NumBuckets - 1); } /* BucketFor */
Definition at line 1233 of file intproto.cpp.
{ /* ** Parameters: ** Bucket bucket whose start is to be computed ** Offset offset used to map params to buckets ** NumBuckets total number of buckets ** Globals: none ** Operation: This routine returns the parameter value which ** corresponds to the beginning of the specified bucket. ** The bucket number should have been generated using the ** BucketFor() function with parameters Offset and NumBuckets. ** Return: Param value corresponding to start position of Bucket. ** Exceptions: none ** History: Thu Feb 14 13:24:33 1991, DSJ, Created. */ return (((FLOAT32) Bucket / NumBuckets) - Offset); } /* BucketStart */
Definition at line 447 of file intproto.cpp.
{ /* ** Parameters: ** Param parameter value to map into a circular bucket ** Offset amount to shift param before mapping it ** NumBuckets number of buckets to map param into ** Globals: none ** Operation: This routine maps a parameter value into a bucket between ** 0 and NumBuckets-1. Offset is added to the parameter ** before mapping it. Values which map to buckets outside ** the range are wrapped to a new value in a circular fashion. ** Mapping is done by truncating rather than rounding. ** Return: Bucket number corresponding to Param + Offset. ** Exceptions: none ** History: Thu Feb 14 13:24:33 1991, DSJ, Created. */ int Bucket; Bucket = static_cast<int>(MapParam(Param, Offset, NumBuckets)); if (Bucket < 0) Bucket += NumBuckets; else if (Bucket >= NumBuckets) Bucket -= NumBuckets; return Bucket; } /* CircBucketFor */
void ConvertConfig | ( | BIT_VECTOR | Config, |
int | ConfigId, | ||
INT_CLASS | Class | ||
) |
Definition at line 494 of file intproto.cpp.
{ /* ** Parameters: ** Config config to be added to class ** ConfigId id to be used for new config ** Class class to add new config to ** Globals: none ** Operation: This operation updates the config vectors of all protos ** in Class to indicate that the protos with 1's in Config ** belong to a new configuration identified by ConfigId. ** It is assumed that the length of the Config bit vector is ** equal to the number of protos in Class. ** Return: none ** Exceptions: none ** History: Mon Feb 11 14:57:31 1991, DSJ, Created. */ int ProtoId; INT_PROTO Proto; int TotalLength; for (ProtoId = 0, TotalLength = 0; ProtoId < Class->NumProtos; ProtoId++) { if (test_bit(Config, ProtoId)) { Proto = ProtoForProtoId(Class, ProtoId); SET_BIT(Proto->Configs, ConfigId); TotalLength += Class->ProtoLengths[ProtoId]; } } Class->ConfigLengths[ConfigId] = TotalLength; } /* ConvertConfig */
ScrollView* CreateFeatureSpaceWindow | ( | const char * | name, |
int | xpos, | ||
int | ypos | ||
) |
Definition at line 1991 of file intproto.cpp.
{ return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true); }
void DisplayIntFeature | ( | const INT_FEATURE_STRUCT * | Feature, |
FLOAT32 | Evidence | ||
) |
Definition at line 638 of file intproto.cpp.
{ /* ** Parameters: ** Feature pico-feature to be displayed ** Evidence best evidence for this feature (0-1) ** Globals: ** FeatureShapes global display list for features ** Operation: This routine renders the specified feature into a ** global display list. ** Return: none ** Exceptions: none ** History: Thu Mar 21 14:45:04 1991, DSJ, Created. */ ScrollView::Color color = GetMatchColorFor(Evidence); RenderIntFeature(IntMatchWindow, Feature, color); if (FeatureDisplayWindow) { RenderIntFeature(FeatureDisplayWindow, Feature, color); } } /* DisplayIntFeature */
Definition at line 660 of file intproto.cpp.
{ /* ** Parameters: ** Class class to take proto from ** ProtoId id of proto in Class to be displayed ** Evidence total evidence for proto (0-1) ** Globals: ** ProtoShapes global display list for protos ** Operation: This routine renders the specified proto into a ** global display list. ** Return: none ** Exceptions: none ** History: Thu Mar 21 14:45:04 1991, DSJ, Created. */ ScrollView::Color color = GetMatchColorFor(Evidence); RenderIntProto(IntMatchWindow, Class, ProtoId, color); if (ProtoDisplayWindow) { RenderIntProto(ProtoDisplayWindow, Class, ProtoId, color); } } /* DisplayIntProto */
void DoFill | ( | FILL_SPEC * | FillSpec, |
CLASS_PRUNER_STRUCT * | Pruner, | ||
register uinT32 | ClassMask, | ||
register uinT32 | ClassCount, | ||
register uinT32 | WordIndex | ||
) |
Definition at line 1274 of file intproto.cpp.
{ /* ** Parameters: ** FillSpec specifies which bits to fill in pruner ** Pruner class pruner to be filled ** ClassMask indicates which bits to change in each word ** ClassCount indicates what to change bits to ** WordIndex indicates which word to change ** Globals: none ** Operation: This routine fills in the section of a class pruner ** corresponding to a single x value for a single proto of ** a class. ** Return: none ** Exceptions: none ** History: Tue Feb 19 11:11:29 1991, DSJ, Created. */ register int X, Y, Angle; register uinT32 OldWord; X = FillSpec->X; if (X < 0) X = 0; if (X >= NUM_CP_BUCKETS) X = NUM_CP_BUCKETS - 1; if (FillSpec->YStart < 0) FillSpec->YStart = 0; if (FillSpec->YEnd >= NUM_CP_BUCKETS) FillSpec->YEnd = NUM_CP_BUCKETS - 1; for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++) for (Angle = FillSpec->AngleStart; TRUE; CircularIncrement (Angle, NUM_CP_BUCKETS)) { OldWord = Pruner->p[X][Y][Angle][WordIndex]; if (ClassCount > (OldWord & ClassMask)) { OldWord &= ~ClassMask; OldWord |= ClassCount; Pruner->p[X][Y][Angle][WordIndex] = OldWord; } if (Angle == FillSpec->AngleEnd) break; } } /* DoFill */
BOOL8 FillerDone | ( | TABLE_FILLER * | Filler | ) |
Definition at line 1324 of file intproto.cpp.
{ /* ** Parameters: ** Filler table filler to check if done ** Globals: none ** Operation: Return TRUE if the specified table filler is done, i.e. ** if it has no more lines to fill. ** Return: TRUE if no more lines to fill, FALSE otherwise. ** Exceptions: none ** History: Tue Feb 19 10:08:05 1991, DSJ, Created. */ FILL_SWITCH *Next; Next = &(Filler->Switch[Filler->NextSwitch]); if (Filler->X > Next->X && Next->Type == LastSwitch) return (TRUE); else return (FALSE); } /* FillerDone */
void FillPPCircularBits | ( | uinT32 | ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], |
int | Bit, | ||
FLOAT32 | Center, | ||
FLOAT32 | Spread, | ||
bool | debug | ||
) |
Definition at line 1348 of file intproto.cpp.
{ /* ** Parameters: ** ParamTable table of bit vectors, one per param bucket ** Bit bit position in vectors to be filled ** Center center of filled area ** Spread spread of filled area ** Globals: none ** Operation: This routine sets Bit in each bit vector whose ** bucket lies within the range Center +- Spread. The fill ** is done for a circular dimension, i.e. bucket 0 is adjacent ** to the last bucket. It is assumed that Center and Spread ** are expressed in a circular coordinate system whose range ** is 0 to 1. ** Return: none ** Exceptions: none ** History: Tue Oct 16 09:26:54 1990, DSJ, Created. */ int i, FirstBucket, LastBucket; if (Spread > 0.5) Spread = 0.5; FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS); if (FirstBucket < 0) FirstBucket += NUM_PP_BUCKETS; LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS); if (LastBucket >= NUM_PP_BUCKETS) LastBucket -= NUM_PP_BUCKETS; if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket); for (i = FirstBucket; TRUE; CircularIncrement (i, NUM_PP_BUCKETS)) { SET_BIT (ParamTable[i], Bit); /* exit loop after we have set the bit for the last bucket */ if (i == LastBucket) break; } } /* FillPPCircularBits */
void FillPPLinearBits | ( | uinT32 | ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], |
int | Bit, | ||
FLOAT32 | Center, | ||
FLOAT32 | Spread, | ||
bool | debug | ||
) |
Definition at line 1392 of file intproto.cpp.
{ /* ** Parameters: ** ParamTable table of bit vectors, one per param bucket ** Bit bit number being filled ** Center center of filled area ** Spread spread of filled area ** Globals: none ** Operation: This routine sets Bit in each bit vector whose ** bucket lies within the range Center +- Spread. The fill ** is done for a linear dimension, i.e. there is no wrap-around ** for this dimension. It is assumed that Center and Spread ** are expressed in a linear coordinate system whose range ** is approximately 0 to 1. Values outside this range will ** be clipped. ** Return: none ** Exceptions: none ** History: Tue Oct 16 09:26:54 1990, DSJ, Created. */ int i, FirstBucket, LastBucket; FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS); if (FirstBucket < 0) FirstBucket = 0; LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS); if (LastBucket >= NUM_PP_BUCKETS) LastBucket = NUM_PP_BUCKETS - 1; if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket); for (i = FirstBucket; i <= LastBucket; i++) SET_BIT (ParamTable[i], Bit); } /* FillPPLinearBits */
void free_int_class | ( | INT_CLASS | int_class | ) |
Definition at line 735 of file intproto.cpp.
{ int i; for (i = 0; i < int_class->NumProtoSets; i++) { Efree (int_class->ProtoSets[i]); } if (int_class->ProtoLengths != NULL) { Efree (int_class->ProtoLengths); } Efree(int_class); }
void free_int_templates | ( | INT_TEMPLATES | templates | ) |
Definition at line 774 of file intproto.cpp.
{ int i; for (i = 0; i < templates->NumClasses; i++) free_int_class(templates->Class[i]); for (i = 0; i < templates->NumClassPruners; i++) delete templates->ClassPruners[i]; Efree(templates); }
Definition at line 1508 of file intproto.cpp.
{ /* ** Parameters: ** Level "tightness" level to return pads for ** EndPad place to put end pad for Level ** SidePad place to put side pad for Level ** AnglePad place to put angle pad for Level ** Globals: none ** Operation: This routine copies the appropriate global pad variables ** into EndPad, SidePad, and AnglePad. This is a kludge used ** to get around the fact that global control variables cannot ** be arrays. If the specified level is illegal, the tightest ** possible pads are returned. ** Return: none (results are returned in EndPad, SidePad, and AnglePad. ** Exceptions: none ** History: Thu Feb 14 08:26:49 1991, DSJ, Created. */ switch (Level) { case 0: *EndPad = classify_cp_end_pad_loose * GetPicoFeatureLength (); *SidePad = classify_cp_side_pad_loose * GetPicoFeatureLength (); *AnglePad = classify_cp_angle_pad_loose / 360.0; break; case 1: *EndPad = classify_cp_end_pad_medium * GetPicoFeatureLength (); *SidePad = classify_cp_side_pad_medium * GetPicoFeatureLength (); *AnglePad = classify_cp_angle_pad_medium / 360.0; break; case 2: *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength (); *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength (); *AnglePad = classify_cp_angle_pad_tight / 360.0; break; default: *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength (); *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength (); *AnglePad = classify_cp_angle_pad_tight / 360.0; break; } if (*AnglePad > 0.5) *AnglePad = 0.5; } /* GetCPPadsForLevel */
ScrollView::Color GetMatchColorFor | ( | FLOAT32 | Evidence | ) |
Definition at line 1560 of file intproto.cpp.
{ /* ** Parameters: ** Evidence evidence value to return color for ** Globals: none ** Operation: ** Return: Color which corresponds to specified Evidence value. ** Exceptions: none ** History: Thu Mar 21 15:24:52 1991, DSJ, Created. */ assert (Evidence >= 0.0); assert (Evidence <= 1.0); if (Evidence >= 0.90) return ScrollView::WHITE; else if (Evidence >= 0.75) return ScrollView::GREEN; else if (Evidence >= 0.50) return ScrollView::RED; else return ScrollView::BLUE; } /* GetMatchColorFor */
void GetNextFill | ( | TABLE_FILLER * | Filler, |
FILL_SPEC * | Fill | ||
) |
Definition at line 1586 of file intproto.cpp.
{ /* ** Parameters: ** Filler filler to get next fill spec from ** Fill place to put spec for next fill ** Globals: none ** Operation: This routine returns (in Fill) the specification of ** the next line to be filled from Filler. FillerDone() should ** always be called before GetNextFill() to ensure that we ** do not run past the end of the fill table. ** Return: none (results are returned in Fill) ** Exceptions: none ** History: Tue Feb 19 10:17:42 1991, DSJ, Created. */ FILL_SWITCH *Next; /* compute the fill assuming no switches will be encountered */ Fill->AngleStart = Filler->AngleStart; Fill->AngleEnd = Filler->AngleEnd; Fill->X = Filler->X; Fill->YStart = Filler->YStart >> 8; Fill->YEnd = Filler->YEnd >> 8; /* update the fill info and the filler for ALL switches at this X value */ Next = &(Filler->Switch[Filler->NextSwitch]); while (Filler->X >= Next->X) { Fill->X = Filler->X = Next->X; if (Next->Type == StartSwitch) { Fill->YStart = Next->Y; Filler->StartDelta = Next->Delta; Filler->YStart = Next->YInit; } else if (Next->Type == EndSwitch) { Fill->YEnd = Next->Y; Filler->EndDelta = Next->Delta; Filler->YEnd = Next->YInit; } else { /* Type must be LastSwitch */ break; } Filler->NextSwitch++; Next = &(Filler->Switch[Filler->NextSwitch]); } /* prepare the filler for the next call to this routine */ Filler->X++; Filler->YStart += Filler->StartDelta; Filler->YEnd += Filler->EndDelta; } /* GetNextFill */
void InitFeatureDisplayWindowIfReqd | ( | ) |
Initializes the feature display window if it is not already initialized.
Definition at line 1982 of file intproto.cpp.
{ if (FeatureDisplayWindow == NULL) { FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow", 50, 700); } }
void InitIntMatchWindowIfReqd | ( | ) |
Initializes the int matcher window if it is not already initialized.
Definition at line 1950 of file intproto.cpp.
{ if (IntMatchWindow == NULL) { IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200); SVMenuNode* popup_menu = new SVMenuNode(); popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE, "x", "Class to debug"); popup_menu->AddChild("Debug Static classes", IDA_STATIC, "x", "Class to debug"); popup_menu->AddChild("Debug Both", IDA_BOTH, "x", "Class to debug"); popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX, "0", "Index to debug"); popup_menu->BuildMenu(IntMatchWindow, false); } }
void InitProtoDisplayWindowIfReqd | ( | ) |
Initializes the proto display window if it is not already initialized.
Definition at line 1971 of file intproto.cpp.
{ if (ProtoDisplayWindow == NULL) { ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow", 550, 200); } }
void InitTableFiller | ( | FLOAT32 | EndPad, |
FLOAT32 | SidePad, | ||
FLOAT32 | AnglePad, | ||
PROTO | Proto, | ||
TABLE_FILLER * | Filler | ||
) |
This routine computes a data structure (Filler) which can be used to fill in a rectangle surrounding the specified Proto.
EndPad,SidePad,AnglePad | padding to add to proto |
Proto | proto to create a filler for |
Filler | place to put table filler |
Globals: none
Definition at line 1654 of file intproto.cpp.
{ FLOAT32 Angle; FLOAT32 X, Y, HalfLength; FLOAT32 Cos, Sin; FLOAT32 XAdjust, YAdjust; FPOINT Start, Switch1, Switch2, End; int S1 = 0; int S2 = 1; Angle = Proto->Angle; X = Proto->X; Y = Proto->Y; HalfLength = Proto->Length / 2.0; Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB); Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB); Filler->NextSwitch = 0; if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) { /* horizontal proto - handle as special case */ Filler->X = BucketFor(X - HalfLength - EndPad, XS, NB); Filler->YStart = BucketFor(Y - SidePad, YS, NB * 256); Filler->YEnd = BucketFor(Y + SidePad, YS, NB * 256); Filler->StartDelta = 0; Filler->EndDelta = 0; Filler->Switch[0].Type = LastSwitch; Filler->Switch[0].X = BucketFor(X + HalfLength + EndPad, XS, NB); } else if (fabs(Angle - 0.25) < HV_TOLERANCE || fabs(Angle - 0.75) < HV_TOLERANCE) { /* vertical proto - handle as special case */ Filler->X = BucketFor(X - SidePad, XS, NB); Filler->YStart = BucketFor(Y - HalfLength - EndPad, YS, NB * 256); Filler->YEnd = BucketFor(Y + HalfLength + EndPad, YS, NB * 256); Filler->StartDelta = 0; Filler->EndDelta = 0; Filler->Switch[0].Type = LastSwitch; Filler->Switch[0].X = BucketFor(X + SidePad, XS, NB); } else { /* diagonal proto */ if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) { /* rising diagonal proto */ Angle *= 2.0 * PI; Cos = fabs(cos(Angle)); Sin = fabs(sin(Angle)); /* compute the positions of the corners of the acceptance region */ Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin; Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos; End.x = 2.0 * X - Start.x; End.y = 2.0 * Y - Start.y; Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin; Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos; Switch2.x = 2.0 * X - Switch1.x; Switch2.y = 2.0 * Y - Switch1.y; if (Switch1.x > Switch2.x) { S1 = 1; S2 = 0; } /* translate into bucket positions and deltas */ Filler->X = (inT8) MapParam(Start.x, XS, NB); Filler->StartDelta = -(inT16) ((Cos / Sin) * 256); Filler->EndDelta = (inT16) ((Sin / Cos) * 256); XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x; YAdjust = XAdjust * Cos / Sin; Filler->YStart = (inT16) MapParam(Start.y - YAdjust, YS, NB * 256); YAdjust = XAdjust * Sin / Cos; Filler->YEnd = (inT16) MapParam(Start.y + YAdjust, YS, NB * 256); Filler->Switch[S1].Type = StartSwitch; Filler->Switch[S1].X = (inT8) MapParam(Switch1.x, XS, NB); Filler->Switch[S1].Y = (inT8) MapParam(Switch1.y, YS, NB); XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB); YAdjust = XAdjust * Sin / Cos; Filler->Switch[S1].YInit = (inT16) MapParam(Switch1.y - YAdjust, YS, NB * 256); Filler->Switch[S1].Delta = Filler->EndDelta; Filler->Switch[S2].Type = EndSwitch; Filler->Switch[S2].X = (inT8) MapParam(Switch2.x, XS, NB); Filler->Switch[S2].Y = (inT8) MapParam(Switch2.y, YS, NB); XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB); YAdjust = XAdjust * Cos / Sin; Filler->Switch[S2].YInit = (inT16) MapParam(Switch2.y + YAdjust, YS, NB * 256); Filler->Switch[S2].Delta = Filler->StartDelta; Filler->Switch[2].Type = LastSwitch; Filler->Switch[2].X = (inT8)MapParam(End.x, XS, NB); } else { /* falling diagonal proto */ Angle *= 2.0 * PI; Cos = fabs(cos(Angle)); Sin = fabs(sin(Angle)); /* compute the positions of the corners of the acceptance region */ Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin; Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos; End.x = 2.0 * X - Start.x; End.y = 2.0 * Y - Start.y; Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin; Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos; Switch2.x = 2.0 * X - Switch1.x; Switch2.y = 2.0 * Y - Switch1.y; if (Switch1.x > Switch2.x) { S1 = 1; S2 = 0; } /* translate into bucket positions and deltas */ Filler->X = (inT8) MapParam(Start.x, XS, NB); Filler->StartDelta = -(inT16) ((Sin / Cos) * 256); Filler->EndDelta = (inT16) ((Cos / Sin) * 256); XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x; YAdjust = XAdjust * Sin / Cos; Filler->YStart = (inT16) MapParam(Start.y - YAdjust, YS, NB * 256); YAdjust = XAdjust * Cos / Sin; Filler->YEnd = (inT16) MapParam(Start.y + YAdjust, YS, NB * 256); Filler->Switch[S1].Type = EndSwitch; Filler->Switch[S1].X = (inT8) MapParam(Switch1.x, XS, NB); Filler->Switch[S1].Y = (inT8) MapParam(Switch1.y, YS, NB); XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB); YAdjust = XAdjust * Sin / Cos; Filler->Switch[S1].YInit = (inT16) MapParam(Switch1.y + YAdjust, YS, NB * 256); Filler->Switch[S1].Delta = Filler->StartDelta; Filler->Switch[S2].Type = StartSwitch; Filler->Switch[S2].X = (inT8) MapParam(Switch2.x, XS, NB); Filler->Switch[S2].Y = (inT8) MapParam(Switch2.y, YS, NB); XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB); YAdjust = XAdjust * Cos / Sin; Filler->Switch[S2].YInit = (inT16) MapParam(Switch2.y - YAdjust, YS, NB * 256); Filler->Switch[S2].Delta = Filler->EndDelta; Filler->Switch[2].Type = LastSwitch; Filler->Switch[2].X = (inT8) MapParam(End.x, XS, NB); } } } /* InitTableFiller */
INT_CLASS NewIntClass | ( | int | MaxNumProtos, |
int | MaxNumConfigs | ||
) |
Definition at line 683 of file intproto.cpp.
{ /* ** Parameters: ** MaxNumProtos number of protos to allocate space for ** MaxNumConfigs number of configs to allocate space for ** Globals: none ** Operation: This routine creates a new integer class data structure ** and returns it. Sufficient space is allocated ** to handle the specified number of protos and configs. ** Return: New class created. ** Exceptions: none ** History: Fri Feb 8 10:51:23 1991, DSJ, Created. */ INT_CLASS Class; PROTO_SET ProtoSet; int i; assert(MaxNumConfigs <= MAX_NUM_CONFIGS); Class = (INT_CLASS) Emalloc(sizeof(INT_CLASS_STRUCT)); Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) / PROTOS_PER_PROTO_SET); assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS); Class->NumProtos = 0; Class->NumConfigs = 0; for (i = 0; i < Class->NumProtoSets; i++) { /* allocate space for a proto set, install in class, and initialize */ ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT)); memset(ProtoSet, 0, sizeof(*ProtoSet)); Class->ProtoSets[i] = ProtoSet; /* allocate space for the proto lengths and install in class */ } if (MaxNumIntProtosIn (Class) > 0) { Class->ProtoLengths = (uinT8 *)Emalloc(MaxNumIntProtosIn (Class) * sizeof (uinT8)); memset(Class->ProtoLengths, 0, MaxNumIntProtosIn(Class) * sizeof(*Class->ProtoLengths)); } else { Class->ProtoLengths = NULL; } memset(Class->ConfigLengths, 0, sizeof(Class->ConfigLengths)); return (Class); } /* NewIntClass */
INT_TEMPLATES NewIntTemplates | ( | ) |
Definition at line 749 of file intproto.cpp.
{ /* ** Parameters: none ** Globals: none ** Operation: This routine allocates a new set of integer templates ** initialized to hold 0 classes. ** Return: The integer templates created. ** Exceptions: none ** History: Fri Feb 8 08:38:51 1991, DSJ, Created. */ INT_TEMPLATES T; int i; T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT)); T->NumClasses = 0; T->NumClassPruners = 0; for (i = 0; i < MAX_NUM_CLASSES; i++) ClassForClassId (T, i) = NULL; return (T); } /* NewIntTemplates */
void RenderIntFeature | ( | ScrollView * | window, |
const INT_FEATURE_STRUCT * | Feature, | ||
ScrollView::Color | color | ||
) |
Definition at line 1822 of file intproto.cpp.
{ FLOAT32 X, Y, Dx, Dy, Length; window->Pen(color); assert(Feature != NULL); assert(color != 0); X = Feature->X; Y = Feature->Y; Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE; // The -PI has no significant effect here, but the value of Theta is computed // using BinaryAnglePlusPi in intfx.cpp. Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * PI - PI); Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * PI - PI); window->SetCursor(X, Y); window->DrawTo(X + Dx, Y + Dy); } /* RenderIntFeature */
void RenderIntProto | ( | ScrollView * | window, |
INT_CLASS | Class, | ||
PROTO_ID | ProtoId, | ||
ScrollView::Color | color | ||
) |
Definition at line 1860 of file intproto.cpp.
{ PROTO_SET ProtoSet; INT_PROTO Proto; int ProtoSetIndex; int ProtoWordIndex; FLOAT32 Length; int Xmin, Xmax, Ymin, Ymax; FLOAT32 X, Y, Dx, Dy; uinT32 ProtoMask; int Bucket; assert(ProtoId >= 0); assert(Class != NULL); assert(ProtoId < Class->NumProtos); assert(color != 0); window->Pen(color); ProtoSet = Class->ProtoSets[SetForProto(ProtoId)]; ProtoSetIndex = IndexForProto(ProtoId); Proto = &(ProtoSet->Protos[ProtoSetIndex]); Length = (Class->ProtoLengths[ProtoId] * GetPicoFeatureLength() * INT_CHAR_NORM_RANGE); ProtoMask = PPrunerMaskFor(ProtoId); ProtoWordIndex = PPrunerWordIndexFor(ProtoId); // find the x and y extent of the proto from the proto pruning table Xmin = Ymin = NUM_PP_BUCKETS; Xmax = Ymax = 0; for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) { if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) { UpdateRange(Bucket, &Xmin, &Xmax); } if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) { UpdateRange(Bucket, &Ymin, &Ymax); } } X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE; Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE; // The -PI has no significant effect here, but the value of Theta is computed // using BinaryAnglePlusPi in intfx.cpp. Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * PI - PI); Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * PI - PI); window->SetCursor(X - Dx, Y - Dy); window->DrawTo(X + Dx, Y + Dy); } /* RenderIntProto */
int TruncateParam | ( | FLOAT32 | Param, |
int | Min, | ||
int | Max, | ||
char * | Id | ||
) |
This routine truncates Param to lie within the range of Min-Max inclusive. If a truncation is performed, and Id is not null, an warning message is printed.
Param | parameter value to be truncated |
Min,Max | parameter limits (inclusive) |
Id | string id of parameter for error messages |
Globals: none
Definition at line 1928 of file intproto.cpp.
void UpdateMatchDisplay | ( | ) |
Definition at line 476 of file intproto.cpp.
{ /* ** Parameters: none ** Globals: ** FeatureShapes display list for features ** ProtoShapes display list for protos ** Operation: This routine clears the global feature and proto ** display lists. ** Return: none ** Exceptions: none ** History: Thu Mar 21 15:40:19 1991, DSJ, Created. */ if (IntMatchWindow != NULL) IntMatchWindow->Update(); } /* ClearMatchDisplay */
double classify_cp_angle_pad_loose = 45.0 |
"Class Pruner Angle Pad Loose"
Definition at line 191 of file intproto.cpp.
double classify_cp_angle_pad_medium = 20.0 |
"Class Pruner Angle Pad Medium"
Definition at line 193 of file intproto.cpp.
double classify_cp_angle_pad_tight = 10.0 |
"CLass Pruner Angle Pad Tight"
Definition at line 195 of file intproto.cpp.
double classify_cp_end_pad_loose = 0.5 |
"Class Pruner End Pad Loose"
Definition at line 196 of file intproto.cpp.
double classify_cp_end_pad_medium = 0.5 |
"Class Pruner End Pad Medium"
Definition at line 197 of file intproto.cpp.
double classify_cp_end_pad_tight = 0.5 |
"Class Pruner End Pad Tight"
Definition at line 198 of file intproto.cpp.
double classify_cp_side_pad_loose = 2.5 |
"Class Pruner Side Pad Loose"
Definition at line 199 of file intproto.cpp.
double classify_cp_side_pad_medium = 1.2 |
"Class Pruner Side Pad Medium"
Definition at line 200 of file intproto.cpp.
double classify_cp_side_pad_tight = 0.6 |
"Class Pruner Side Pad Tight"
Definition at line 201 of file intproto.cpp.
int classify_num_cp_levels = 3 |
"Number of Class Pruner Levels"
Definition at line 189 of file intproto.cpp.
double classify_pp_angle_pad = 45.0 |
"Proto Pruner Angle Pad"
Definition at line 202 of file intproto.cpp.
double classify_pp_end_pad = 0.5 |
"Proto Prune End Pad"
Definition at line 203 of file intproto.cpp.
double classify_pp_side_pad = 2.5 |
"Proto Pruner Side Pad"
Definition at line 204 of file intproto.cpp.
ScrollView* FeatureDisplayWindow = NULL |
Definition at line 181 of file intproto.cpp.
ScrollView* IntMatchWindow = NULL |
Definition at line 180 of file intproto.cpp.
ScrollView* ProtoDisplayWindow = NULL |
Definition at line 182 of file intproto.cpp.