BOOL TrapsList::ExpandArray(void) { // Work out how many entries to allocate. // Each item is small, so we allocate a reasonably large number // Note that potential implementation of dashed lines could create a lot of // TrapEdgeLists (one per dash), so we need lots of spare capacity to cope // with this situation. I've therefore erred on the generous side. const INT32 AllocSize = CurrentSize + 64; if (pTraps == NULL) { // We have no array yet, so allocate one pTraps = (TrapEdgeList **) CCMalloc(AllocSize * sizeof(TrapEdgeList *)); if (pTraps == NULL) return(FALSE); } else { // We have an array - we must make it larger TrapEdgeList **pNewBuf = (TrapEdgeList **) CCRealloc(pTraps, AllocSize * sizeof(TrapEdgeList *)); if (pNewBuf == NULL) return(FALSE); pTraps = pNewBuf; } // Success. Update the current size value CurrentSize = AllocSize; // Initialise the pointers to safe values for (UINT32 Index = Used; Index < CurrentSize; Index++) pTraps[Index] = NULL; return(TRUE); }
BOOL RenderStack::GrowStack() { INT32 FirstNewItem = 0; if (TheStack == NULL) { // Try to allocate initial memory block for the stack. TheStack = (AttributeRec *) CCMalloc(InitialStackSize * ITEM_SIZE); // Complain and return if it didn't work. if (TheStack == NULL) return FALSE; // Update stack limit to reflect new size StackLimit = InitialStackSize; } else { // if (IsUserName("Tim")) // TRACE( _T("Growing heap from %d to %d entries\n"), // StackLimit, StackLimit + StackGranularity); // Increase the stack allocation AttributeRec *NewStack = (AttributeRec *) CCRealloc(TheStack, (StackLimit + StackGranularity) * ITEM_SIZE); // Complain if no more memory if (NewStack == NULL) return FALSE; // Otherwise use this new block TheStack = NewStack; // Make sure only new items are initialised FirstNewItem = StackLimit; // Update stack limit to reflect new size StackLimit += StackGranularity; } // Initialise the stack elements for (UINT32 i = FirstNewItem; i < StackLimit; i++) { TheStack[i].pAttrValue = NULL; TheStack[i].ContextLevel = 0; TheStack[i].Temporary = FALSE; } // Return success return TRUE; }
LPVOID TunedMemory::LimitedCCRealloc(LPVOID buf, size_t NewSize) { // Find out how big the block is at the moment size_t OldSize = CCGetBlockSize(buf); // Resize the block LPVOID Memory = CCRealloc( buf, NewSize ); // If it got bigger, then decrease the available RAM, // otherwise we increase it if ((Memory!=NULL) && (!IsInfinite)) { AvailableRAM -= (NewSize - OldSize); } // return what we got return Memory; }
BOOL MemoryBlock::Grow( UINT32 OldSize, UINT32 NewSize, LPVOID *Pointer ) { #if USE_STD_ALLOC NewSize = GetRoundedSize( NewSize ); // round new size up if( NewSize == m_RoundedSize ) return TRUE; // if same physical size LPVOID NewPtr = CCRealloc( *Pointer, NewSize ); if (NewPtr==NULL) { TRACEUSER( "Andy", wxT("CCRealloc growing from %ld to %ld failed\n"), OldSize, NewSize); return FALSE; } *Pointer = m_pMemBlk = NewPtr; m_RoundedSize = NewSize; return TRUE; #elif USE_VM_BLOCKS NewSize = GetRoundedSize( NewSize ); // round new size up if (NewSize == RoundedSize) return TRUE; // if same physical size LPVOID NewPtr = VirtualAlloc( MemBase, NewSize, MEM_COMMIT, PAGE_READWRITE ); if (NewPtr==NULL) { TRACEUSER( "Andy", wxT("VirtualAlloc growing from %ld to %ld failed\n"), OldSize, NewSize); return FALSE; } *Pointer = NewPtr; RoundedSize = NewSize; return TRUE; #else const UINT32 Flags = AutoZero ? GMEM_ZEROINIT : 0; #ifndef WIN32 if (NewSize > MAX_BLOCK) return FALSE; #endif return DoGrowGlobalHandle( &MemHandle, OldSize, NewSize, Flags, Pointer ); #endif }
BOOL TrapEdgeList::ExpandArray(void) { // Work out how many entries to allocate. Note that I use a fairly large number // so that we don't have to reallocate the array very often. Each structure is // small, so the memory usage is fairly low, although it must be noted that // a dashed line could potentially generate quite a pile of these lists! INT32 AllocSize = CurrentSize + 512; if (pParentList != NULL && pParentList->GetRepeatLength() > 0) { // If it's a repeating stroke, then we must be far more careful about memory usage! // (i.e. if there are 1000 repeats along a stroke, each taking 15kB, we'll eat 15MB!) // We assume that repeats are small and hence will not need very many entries, and // then if (and only if) we find we have to realloc to make the array bigger, we jump // in bigger steps. if (CurrentSize == 0) AllocSize = CurrentSize + 4; else AllocSize = CurrentSize + 16; } if (pEdges == NULL) { // We have no array yet, so allocate one pEdges = (TrapEdge *) CCMalloc(AllocSize * sizeof(TrapEdge)); if (pEdges == NULL) return(FALSE); } else { // We have an array - we must make it larger TrapEdge *pNewBuf = (TrapEdge *) CCRealloc(pEdges, AllocSize * sizeof(TrapEdge)); if (pNewBuf == NULL) return(FALSE); pEdges = pNewBuf; } // Success. Update the current size value CurrentSize = AllocSize; return(TRUE); }
BOOL MemoryBlock::Shrink( UINT32 OldSize, UINT32 NewSize, LPVOID *Pointer ) { #if USE_STD_ALLOC OldSize = GetRoundedSize( OldSize ); NewSize = GetRoundedSize( NewSize ); if (OldSize == NewSize) return TRUE; // no change required if (OldSize < NewSize) { ENSURE(FALSE, "Cannot Shrink backwards"); return FALSE; } // if same physical size LPVOID NewPtr = CCRealloc( *Pointer, NewSize ); if (NewPtr==NULL) { TRACEUSER( "Andy", wxT("CCRealloc growing from %ld to %ld failed\n"), OldSize, NewSize); return FALSE; } *Pointer = m_pMemBlk = NewPtr; m_RoundedSize = NewSize; return TRUE; #elif USE_VM_BLOCKS // we do a shrink by freeing up spare blocks OldSize = GetRoundedSize( OldSize ); NewSize = GetRoundedSize( NewSize ); if (OldSize == NewSize) return TRUE; // no change required if (OldSize < NewSize) { ENSURE(FALSE, "Cannot Shrink backwards"); return FALSE; } // lets free up the unwanted bits now BOOL Result = VirtualFree( ((LPBYTE)MemBase)+NewSize, OldSize-NewSize, MEM_DECOMMIT ); if (Result==FALSE) { TRACEUSER( "Andy", wxT("VirtualFree Shrink from %ld to %ld failed\n"), OldSize, NewSize); return FALSE; } RoundedSize = NewSize; return TRUE; #else // the data will be left alone ENSURE( FALSE, "Cannot shrink memory blocks"); return FALSE; #endif }
BOOL FreeHandEPSFilter::ProcessToken() { // Decode the command, and execute it... switch (Token) { // state saving case EPSC_vms: if(!Import_gsave()) return FALSE; break; case EPSC_vmr: if(!Import_grestore()) return FALSE; break; case EPSC_vmrs: if(!Import_grestore()) return FALSE; if(!Import_gsave()) return FALSE; break; // tokens to ignore case EPSC_FREEHAND_IGNOREDTOKEN: break; // tokens which should be ignored and one entry discarded case EPSC_load: // the load part of a fill - discard the /clipper before it case EPSC_fhsetspreadallow: if(!Stack.Discard(1)) goto EPSError; break; case EPSC_concat: if(!Stack.DiscardArray()) goto EPSError; break; // complex paths... case EPSC_eomode: { INT32 ComplexStart; if(!Stack.Pop(&ComplexStart)) goto EPSError; // is this a start of a complex path? if(ComplexStart != TRUE) { ComplexPathMode = FALSE; } else { HadFirstOfComplexPath = FALSE; ComplexPathMode = TRUE; } } break; case EPSC_true: Stack.Push((INT32)TRUE); break; case EPSC_false: Stack.Push((INT32)FALSE); break; case EPSC_u: HadFirstOfComplexPath = FALSE; return EPSFilter::ProcessToken(); break; // colours case EPSC_Ka: case EPSC_ka: { DocColour Colour; if(PopColour(&Colour)) { // Remember this colour for future objects if (Token == EPSC_ka) { if (!SetFillColour(Colour)) goto NoMemory; } else { if (!SetLineColour(Colour)) goto NoMemory; } } else // Invalid colour operands goto EPSError; } break; case EPSC_Xa: case EPSC_xa: { DocColour Colour; if(PopNamedColour(&Colour)) { // Remember this colour for future objects if (Token == EPSC_xa) { if (!SetFillColour(Colour)) goto NoMemory; } else { if (!SetLineColour(Colour)) goto NoMemory; } } else // Invalid colour operands goto EPSError; } break; case EPSC_H: if(ComplexPathMode) { // in complex path mode - make this a filled one, not a discarded one Token = EPSC_S; } return EPSFilter::ProcessToken(); break; case EPSC_h: if(ComplexPathMode) { // in complex path mode - modify and process Token = EPSC_s; return EPSFilter::ProcessToken(); break; } // the hidden path closing operator - a grad fill thingy will follow shortly maybe... // this will prevent it being processed now, although it may get processed later on. HadhToken = TRUE; break; // for clipping masks, do some funky stuff case EPSC_q: // if there's a pending grad fill... if(DoingGradFill) { if(pPath != 0) { // right then, make a copy of the path... NodePath *pPathClone; if(!pPath->NodeCopy((Node **)&pPathClone)) { goto NoMemory; } // copy the flags EPSFlagsDefn EPSFlagsClone = EPSFlags; // send a token to finish and fill the path... Token = (pInkPath->IsFilled)?EPSC_f:EPSC_s; if(!EPSFilter::ProcessToken()) return FALSE; // restore the old fill if(!RestoreCurrentFill()) goto NoMemory; // restore the copy of the path pPath = pPathClone; pInkPath = &pPath->InkPath; // restore the flags EPSFlags = EPSFlagsClone; // definately want to send an h HadhToken = TRUE; } // done the grad fill DoingGradFill = FALSE; // restore the old token Token = EPSC_q; } // clipping started - have we got an h token to send? if(HadhToken) FHEF_SENDh // process this return EPSFilter::ProcessToken(); break; // for now, if there's no path, don't return a W case EPSC_W: if(pPath == 0) { // OK, now we want to get the last path we created, make a copy of it and then install it as the current one if(pLastPathSeen == 0) goto EPSError; // make a copy of it NodePath *pClone; if(!pLastPathSeen->NodeCopy((Node **)&pClone)) goto NoMemory; // delete it's attributes pClone->DeleteChildren(pClone->FindFirstChild()); // make it the current path pPath = pClone; pInkPath = &pPath->InkPath; ThePathType = PATH_NORMAL; EPSFlags.NoAttributes = TRUE; } if(pPath != 0) return EPSFilter::ProcessToken(); break; // we may need to modify path closing things if we're doing a grad fill case EPSC_s: case EPSC_S: if(Token == EPSC_S) { // if we've had an h token but no grad fill, send the h now if(HadhToken) FHEF_SENDh // if we've got a grad fill, modify the token we got if(DoingGradFill) Token = EPSC_b; } // process the possily modified token normally HadhToken = FALSE; return EPSFilter::ProcessToken(); break; // modify path closing for grad fills. case EPSC_n: if(DoingGradFill) { Token = EPSC_f; // we want to fill the thing HadhToken = FALSE; return EPSFilter::ProcessToken(); break; } HadhToken = FALSE; // ignore h's as this is another end path thingy... if(pPath != 0) return EPSFilter::ProcessToken(); break; // unset the had h token for other path closing things case EPSC_N: case EPSC_F: case EPSC_f: case EPSC_B: case EPSC_b: HadhToken = FALSE; return EPSFilter::ProcessToken(); break; // interested in path element things to switch off grad fills case EPSC_m: if(InText) { // if we're doing some text, discard the moveto command if(!Stack.Discard(2)) goto EPSError; break; } case EPSC_l: case EPSC_L: case EPSC_c: case EPSC_C: case EPSC_v: case EPSC_V: case EPSC_y: case EPSC_Y: // maybe we need an h token to be sent if(HadhToken) FHEF_SENDh // stop grad fill if(DoingGradFill) { // turn the grad fill state off DoingGradFill = FALSE; // restore the old fill type RestoreCurrentFill(); } return EPSFilter::ProcessToken(); break; case EPSC_recfill: { // get the colours DocColour StartColour, EndColour; if(!PopColour(&EndColour) || !PopColour(&StartColour)) goto EPSError; // discard the fill type thingy - we can only do colours if(!DiscardFillSubType()) goto EPSError; // OK, now a few coords DocCoord Centre; double Angle; DocRect BBox; if(!Stack.PopCoordPair(&BBox.hi) || !Stack.PopCoordPair(&BBox.lo) || !Stack.Pop(&Angle) || !Stack.PopCoordPair(&Centre)) goto EPSError; // munge the angle a little and get it into radians Angle += 225; Angle = (Angle * (2 * PI)) / 360; // see if we can get a more accurate BBox if(pPath != 0) { BBox = pPath->GetBoundingRect(); Centre.x = BBox.lo.x + (BBox.Width() / 2); Centre.y = BBox.lo.y + (BBox.Height() / 2); } // OK, we've got all the stuff we need to do some niceness on it BBox.Translate(0 - Centre.x, 0 - Centre.y); DocCoord StartPoint, EndPoint; StartPoint.x = Centre.x + (INT32)(((double)BBox.lo.x * cos(Angle)) - ((double)BBox.lo.y * sin(Angle))); StartPoint.y = Centre.y + (INT32)(((double)BBox.lo.x * sin(Angle)) + ((double)BBox.lo.y * cos(Angle))); EndPoint.x = Centre.x + (INT32)(((double)BBox.hi.x * cos(Angle)) - ((double)BBox.hi.y * sin(Angle))); EndPoint.y = Centre.y + (INT32)(((double)BBox.hi.x * sin(Angle)) + ((double)BBox.hi.y * cos(Angle))); // store current fill attribute SaveCurrentFill(); // set the fill if(!SetLinearFill(StartColour, EndColour, StartPoint, EndPoint)) goto NoMemory; // say we're doing a grad fill DoingGradFill = TRUE; HadhToken = FALSE; // absorb this } break; case EPSC_radfill: { // get the colours DocColour StartColour, EndColour; if(!PopColour(&StartColour) || !PopColour(&EndColour)) goto EPSError; // get the radius and centre coordinate DocCoord Centre; INT32 Radius; if(!Stack.PopCoord(&Radius) || !Stack.PopCoordPair(&Centre)) goto EPSError; // store current fill attribute SaveCurrentFill(); // set the fill DocCoord EndPoint(Centre.x + Radius, Centre.y); if(!SetRadialFill(StartColour, EndColour, Centre, EndPoint)) goto NoMemory; // say we're doing a grad fill DoingGradFill = TRUE; HadhToken = FALSE; } break; case EPSC_BeginSetup: // there's probably a colour list or something in that there setup thingy - search for the spots token { BOOL Found = FALSE; while(Found == FALSE) { if(!EPSFile->GetToken()) return FALSE; if(EPSFile->GetTokenType() == TOKEN_NORMAL) { if(camStrcmp(TokenBuf, _T("spots")) == 0) { // check to see if the array is about to start if(!EPSFile->GetToken()) return FALSE; if(TokenBuf[0] == '[') { TRACEUSER( "Ben", _T("Found spots\n")); Found = TRUE; } } } if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0) { TRACEUSER( "Ben", _T("Met end of setup without finding spots\n")); break; } if(EPSFile->eof()) goto EPSError; } if(Found == TRUE) { InColours = TRUE; } } break; case EPSC_def: if(InColours) { // finished the colours... TRACEUSER( "Ben", _T("Finished spot colours\n")); // scan for the end of the setup section BOOL Found = FALSE; while(Found == FALSE) { if(!EPSFile->GetToken()) return FALSE; if(EPSFile->GetTokenType() == TOKEN_COMMENT) { if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0) { TRACEUSER( "Ben", _T("Found end of setup\n")); Found = TRUE; } } if(EPSFile->eof()) goto EPSError; } // get the ] off the stack EPSCommand Ignored; Stack.PopCmd(&Ignored); // empty it... Stack.DeleteAll (); InColours = FALSE; } else { // probably a font type thingy - empty the stack including commands Stack.DeleteAll (); } break; case EPSC_newcmykcustomcolor: // OK, here's a named colour... add it to those known { // discard some random thingy if(!Stack.Discard()) goto EPSError; // get the name String_64 ColourName; if(!Stack.Pop(&ColourName)) goto EPSError; // get the components double C, M, Y, K; if(!Stack.Pop(&K) || !Stack.Pop(&Y) || !Stack.Pop(&M) || !Stack.Pop(&C)) goto EPSError; // make the new colour ColourCMYK Colour; Colour.Cyan = C; Colour.Magenta = M; Colour.Yellow = Y; Colour.Key = K; // add it if(!pNewColours->AddColour(&ColourName, &Colour)) goto NoMemory; // add it to the list of colours // this is a bit of a bodge, but never mind. Shouldn't be that bad. IndexedColour *TheNewColour = pNewColours->GetColour(ColourName); if(TheNewColour == 0) goto NoMemory; // add it to the list of colours // enough space? if((ColourArrayEntries + 1) >= ColourArraySize) { TRACEUSER( "Ben", _T("Extening colour array\n")); IndexedColour **NewPtr = (IndexedColour **)CCRealloc(ColourArray, (ColourArraySize + FHEF_COLOURARRAY_CHUNK) * sizeof(IndexedColour *)); if(NewPtr == 0) goto NoMemory; ColourArray = NewPtr; ColourArraySize += FHEF_COLOURARRAY_CHUNK; } // add ColourArray[ColourArrayEntries] = TheNewColour; ColourArrayEntries++; } break; // ignore text stuff case EPSC_makesetfont: if(!Stack.DiscardArray()) goto EPSError; if(!Stack.Discard(1)) goto EPSError; InText = TRUE; break; case EPSC_ts: if(!Stack.Discard(6)) goto EPSError; break; case EPSC_stob: case EPSC_sts: Stack.DeleteAll (); InText = FALSE; break; default: // Token not understood - pass on to base class return EPSFilter::ProcessToken(); } // No errors encountered while parsing this token and its operands. return TRUE; // Error handlers: EPSError: HandleEPSError(); return FALSE; NoMemory: HandleNoMemory(); return FALSE; }