void WriteGlyphAsTGA(FT_Library &library, const std::string &fileName, wchar_t ch, FT_Face &face, int size, const Pixel32 &fontCol, const Pixel32 outlineCol, float outlineWidth) { // Set the size to use. if (FT_Set_Char_Size(face, size << 6, size << 6, 90, 90) == 0) { // Load the glyph we are looking for. FT_UInt gindex = FT_Get_Char_Index(face, ch); if (FT_Load_Glyph(face, gindex, FT_LOAD_NO_BITMAP) == 0) { // Need an outline for this to work. if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { // Render the basic glyph to a span list. Spans spans; RenderSpans(library, &face->glyph->outline, &spans); // Next we need the spans for the outline. Spans outlineSpans; // Set up a stroker. FT_Stroker stroker; FT_Stroker_New(library, &stroker); FT_Stroker_Set(stroker, (int)(outlineWidth * 64), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); FT_Glyph glyph; if (FT_Get_Glyph(face->glyph, &glyph) == 0) { FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1); // Again, this needs to be an outline to work. if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) { // Render the outline spans to the span list FT_Outline *o = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline; RenderSpans(library, o, &outlineSpans); } // Clean up afterwards. FT_Stroker_Done(stroker); FT_Done_Glyph(glyph); // Now we need to put it all together. if (!spans.empty()) { // Figure out what the bounding rect is for both the span lists. Rect rect(spans.front().x, spans.front().y, spans.front().x, spans.front().y); for (Spans::iterator s = spans.begin(); s != spans.end(); ++s) { rect.Include(Vec2(s->x, s->y)); rect.Include(Vec2(s->x + s->width - 1, s->y)); } for (Spans::iterator s = outlineSpans.begin(); s != outlineSpans.end(); ++s) { rect.Include(Vec2(s->x, s->y)); rect.Include(Vec2(s->x + s->width - 1, s->y)); } #if 0 // This is unused in this test but you would need this to draw // more than one glyph. float bearingX = face->glyph->metrics.horiBearingX >> 6; float bearingY = face->glyph->metrics.horiBearingY >> 6; float advance = face->glyph->advance.x >> 6; #endif // Get some metrics of our image. int imgWidth = rect.Width(), imgHeight = rect.Height(), imgSize = imgWidth * imgHeight; // Allocate data for our image and clear it out to transparent. Pixel32 *pxl = new Pixel32[imgSize]; memset(pxl, 0, sizeof(Pixel32) * imgSize); // Loop over the outline spans and just draw them into the // image. for (Spans::iterator s = outlineSpans.begin(); s != outlineSpans.end(); ++s) for (int w = 0; w < s->width; ++w) pxl[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth + s->x - rect.xmin + w)] = Pixel32(outlineCol.r, outlineCol.g, outlineCol.b, s->coverage); // Then loop over the regular glyph spans and blend them into // the image. for (Spans::iterator s = spans.begin(); s != spans.end(); ++s) for (int w = 0; w < s->width; ++w) { Pixel32 &dst = pxl[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth + s->x - rect.xmin + w)]; Pixel32 src = Pixel32(fontCol.r, fontCol.g, fontCol.b, s->coverage); dst.r = (int)(dst.r + ((src.r - dst.r) * src.a) / 255.0f); dst.g = (int)(dst.g + ((src.g - dst.g) * src.a) / 255.0f); dst.b = (int)(dst.b + ((src.b - dst.b) * src.a) / 255.0f); dst.a = MIN(255, dst.a + src.a); } // Dump the image to disk. WriteTGA(fileName, pxl, imgWidth, imgHeight); delete [] pxl; } }
void compareSpacesNeededToSpan(PCBStruct *newProcess,vector <string> &memoryTable,vector <Spans*> &spanVector) { int spacesNeeded = newProcess->getMemoryNeeded(); int spacesDifference = 0; int spacesInSpan = 0; vector<int> spacesDifferenceVector; Spans* current = NULL; for(int i = 0; i < spanVector.size();i++) { current = spanVector[i]; spacesInSpan = current->getEnding() - current->getBeginning() + 1; if(spacesInSpan > spacesNeeded) { spacesDifference = spacesInSpan-spacesNeeded; spacesDifferenceVector.push_back(spacesDifference); } else { spacesDifferenceVector.push_back(-1); } } bestFit(newProcess,memoryTable,spanVector,spacesDifferenceVector); worstFit(newProcess,memoryTable,spanVector,spacesDifferenceVector); }
void nextFit(PCBStruct *newProcess,vector <string> &memoryTable,vector <Spans*> &spanVector) { findSpans(memoryTable,spanVector); int spacesNeeded = newProcess->getMemoryNeeded(); int difference = 0; int range = 0; Spans* current = NULL; for(int i = 0; i < spanVector.size();i++) { current = spanVector[i]; difference = current->getEnding() - current->getBeginning() + 1; if(difference >= spacesNeeded) { range = current->getBeginning() + spacesNeeded; for(int x = current->getBeginning(); x <= spacesNeeded; x++) { memoryTable[x] = newProcess->getProcessName(); } } } findSpans(memoryTable,spanVector); }
void RasterCallback(const int y, const int count, const FT_Span * const spans, void * const user) { Spans *sptr = (Spans *)user; for (int i = 0; i < count; ++i) sptr->push_back(Span(spans[i].x, y, spans[i].len, spans[i].coverage)); }
//joins contigious spans together void coalescing(vector <Spans*> spansVector) { int firstBeginning = 0; int firstEnding = 0; int secondBeginning = 0; int secondEnding = 0; Spans* current = NULL; Spans* next = NULL; for(int i = 0; i < spansVector.size();i++) { current = spansVector[i]; next = spansVector[i+1]; firstBeginning = current->getBeginning(); firstEnding = current->getEnding(); secondBeginning = next->getBeginning(); secondEnding = next->getEnding(); if(firstEnding+1 == secondBeginning) { spansVector[i] = NULL; spansVector[i+1] = NULL; Spans* newSpan = new Spans(firstBeginning,firstEnding,true); newSpan->setBeginning(firstBeginning); newSpan->setEnding(secondEnding); spansVector[i] = newSpan; removeNULLsFromVector(spansVector); } } }
void findSpans(vector <string> &memoryTable,vector <Spans*> &spanVector) { resetSpanVector(spanVector); int sizeofTable = memoryTable.size(); int beginning = -1; int ending = -1; bool Bfound = false; bool Efound = false; bool allFree = true; for(int i = 0; i < sizeofTable; i++) { if(i == sizeofTable-1 && allFree == true) { ending = sizeofTable; Spans *newSpan = new Spans(beginning,ending,true); newSpan->setName("free"); spanVector.push_back(newSpan); Bfound = false; Efound = false; } else if(memoryTable[i] == "free" && Bfound == false) { beginning = i; Bfound = true; } else if(memoryTable[i] != "free" && Efound == false) { allFree = false; ending = i-1; Spans *newSpan = new Spans(beginning,ending,false); newSpan->setName("free"); spanVector.push_back(newSpan); Bfound = false; Efound = false; } } cout << "size: " << spanVector.size() << endl; /* Spans* current = NULL; for(int x = 0; x < signed(spanVector.size());x++) { current = spanVector[x]; cout << current->getName() << "\tBeginning: " << current->getBeginning() << " Ending: " << current->getEnding() << endl; }*/ Sleep(3000); }
void matchVectors(vector <string> &memoryTable, vector <Spans*> spansVector) { int sizeOfTable = memoryTable.size(); int sizeOfVector = spansVector.size(); Spans* current = NULL; for(int i = 0; i < sizeOfVector; i++) { current = spansVector[i]; for(int x = current->getBeginning(); x <= current->getEnding(); x++) { memoryTable[x] = current->getName(); } } }
void organizeVector(vector <Spans*> vectorToOrganize) { int sizeOfVector = vectorToOrganize.size(); Spans* smaller = NULL; Spans* currentSpan = NULL; Spans* nextSpan = NULL; for(int i = 0; i < sizeOfVector; i++) { currentSpan = vectorToOrganize[i]; nextSpan = vectorToOrganize[i]; for(int x = 0; x < sizeOfVector; x++) { if(nextSpan->getBeginning() < currentSpan->getBeginning()) { smaller = nextSpan; vectorToOrganize[x+1] = vectorToOrganize[x]; vectorToOrganize[x] = smaller; } } } }
void worstFit(PCBStruct *newProcess,vector <string> &memoryTable,vector <Spans*> &spanVector, vector<int> differenceVector) { int spacesNeeded = newProcess->getMemoryNeeded(); int biggest = differenceVector[0]; int range = 0; int index = 0; Spans* biggestSpan = NULL; for(int i = 1; i < differenceVector.size();i++) { if(differenceVector[i] > biggest) biggest = differenceVector[i]; biggestSpan = spanVector[i]; index = i; } range = biggestSpan->getBeginning() + spacesNeeded; for(int x = biggestSpan->getBeginning(); x < range; x++) { memoryTable[x] = newProcess->getProcessName(); } }
bool firstFit(PCBStruct *newProcess,vector <string> &memoryTable,vector <Spans*> &spanVector) { int spacesNeeded = newProcess->getMemoryNeeded(); int sizeOfTable = memoryTable.size(); int sizeOfVector = spanVector.size(); int difference = 0; int range = 0; int counter = 0; Spans* currentSpan = NULL; for(int a = 0; a < sizeOfVector; a++) { currentSpan = spanVector[a]; difference = currentSpan->getEnding() - currentSpan->getBeginning() + 1; range = currentSpan->getBeginning() + spacesNeeded; // cout << "needed: " << spacesNeeded << "\tdifference: " << difference << endl; if(difference >= spacesNeeded) { counter = currentSpan->getBeginning(); currentSpan->setName(newProcess->getProcessName()); cout << "255" << endl; for(int i = currentSpan->getBeginning(); i < range; i++) { memoryTable[i] = newProcess->getProcessName(); } return true; } else { return false; } } //cout << "259" << endl << endl << endl; // showMemoryTable(newProcess,memoryTable,spanVector); }
//joins all contiguious spans together at end of table void condensing(vector <Spans*> spanVector, vector <string> memoryTable) { coalescing(spanVector); int totalFreeSpaces = 0; int difference = 0; Spans* current = NULL; for(int i = 0; i < spanVector.size(); i++) { current = spanVector[i]; difference = current->getEnding() - current->getBeginning() + 1; totalFreeSpaces = totalFreeSpaces + difference; } //move everything in memory table up if the address above it is free for(int a = 1; a < memoryTable.size();a++) { if(memoryTable[a-1] == "free") { memoryTable[a -1] = memoryTable[a]; memoryTable[a] = "free"; } } for(int b = memoryTable.size()-totalFreeSpaces; b < totalFreeSpaces; b++) { memoryTable[b] = "free"; } Spans* newSpan = new Spans(memoryTable.size()-totalFreeSpaces,totalFreeSpaces,free); newSpan->setBeginning(memoryTable.size()-totalFreeSpaces); newSpan->setEnding(totalFreeSpaces); resetSpanVector(spanVector); spanVector.push_back(newSpan); }
void fetchPrev(SpanItr &s){ if(s-- == spans.begin()) { uint64_t prvInterval=prevInterval(s->first, timeUnit); s=spans.insert(std::pair<int64_t,spanView*>(prvInterval, new spanView(this, prvInterval, s->first))).first; } };
void fetchNext(SpanItr &s){ if(++s==spans.end()) { uint64_t nxtInterval=nextInterval(s->first, timeUnit); s=spans.insert(std::pair<int64_t,spanView*>(nxtInterval, new spanView(this, s->first,nxtInterval))).first; } };
SpanItr fetchSpan(int64_t idx){ SpanItr ret=spans.find(idx); if(ret!=spans.end()) return ret; spans.insert(std::pair<int64_t,spanView*>(idx, new spanView(this, idx, nextInterval(idx,timeUnit)))).first; };
// The 'move' commands fetch spans as needed then set leftMostSpan and backLeft. void moveTo(uint64_t idx){ SpanItr ret=spans.find(idx); if(ret!=spans.end()) leftMostSpan=ret; else leftMostSpan=spans.insert(std::pair<int64_t,spanView*>(idx, new spanView(this, idx, nextInterval(idx,timeUnit)))).first; backLeft=0; };
//--------------------------------------------------------------------------------- // renderCallback() //--------------------------------------------------------------------------------- void FontMaker::renderCallback( int y, int count, const FT_Span* spans, void* user ) { Spans *sptr = (Spans *)user; for( int i = 0; i < count; ++i ) sptr->push_back( Span( spans[i].x, y, spans[i].len, spans[i].coverage ) ); }