Implemented string view changes for internal drawing functions and added wrapping support and parameters for draw functions.
This commit is contained in:
parent
08e60f2351
commit
d29f7d47bd
@ -55,7 +55,7 @@ void Menu::InitializeConsumableInventoryWindow(){
|
||||
|
||||
inventoryWindow->I(A::LOADOUT_SLOT)=0;
|
||||
|
||||
auto consumableWindow=inventoryWindow->ADD("inventory",InventoryScrollableWindowComponent)({{1,20},{windowSize.x,96.f}},"Consumables","itemName","itemDescription",
|
||||
auto consumableWindow=inventoryWindow->ADD("inventory",InventoryScrollableWindowComponent)({{0,15},{windowSize.x,96.f}},"Consumables","itemName","itemDescription",
|
||||
[&](MenuFuncData data){
|
||||
MenuItemButton*button=(MenuItemButton*)data.component;
|
||||
data.game->ClearLoadoutItem(data.menu.I(A::LOADOUT_SLOT));
|
||||
@ -81,9 +81,9 @@ void Menu::InitializeConsumableInventoryWindow(){
|
||||
Menu::AddInventoryListener(consumableWindow,"Consumables");
|
||||
|
||||
//We don't have to actually populate the inventory list because now when an item gets added, it will automatically add the correct component in for us.
|
||||
inventoryWindow->ADD("Inventory Type Label",MenuLabel)({{0,0},{windowSize.x-1,18}},"Consumables",2,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END;
|
||||
inventoryWindow->ADD("itemName",MenuLabel)(geom2d::rect<float>(vf2d{2,95.f},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW)END;
|
||||
inventoryWindow->ADD("itemDescription",MenuLabel)(geom2d::rect<float>(vf2d{2,122.f},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW)END;
|
||||
inventoryWindow->ADD("Inventory Type Label",MenuLabel)({{0,-5},{windowSize.x-1,18}},"Consumables",2,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END;
|
||||
inventoryWindow->ADD("itemName",MenuLabel)(geom2d::rect<float>(vf2d{2,90.f},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW)END;
|
||||
inventoryWindow->ADD("itemDescription",MenuLabel)(geom2d::rect<float>(vf2d{2,117.f},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW)END;
|
||||
|
||||
auto okButton=inventoryWindow->ADD("OK Button",MenuComponent)({{windowSize.x/2-24,178.f},{48,12}},"Ok",[](MenuFuncData data){Menu::CloseMenu();return true;})END;
|
||||
auto okButton=inventoryWindow->ADD("OK Button",MenuComponent)({{windowSize.x/2-24,173.f},{48,12}},"Ok",[](MenuFuncData data){Menu::CloseMenu();return true;})END;
|
||||
}
|
@ -119,13 +119,15 @@ void MenuComponent::DrawDecal(ViewPort&window,bool focused){
|
||||
}
|
||||
if(showDefaultLabel){
|
||||
vf2d adjustedScale=labelScaling;
|
||||
vi2d labelTextSize=game->GetTextSizeProp(label,rect.size.x);
|
||||
|
||||
if(fitToLabel){
|
||||
float sizeRatio=((game->GetTextSizeProp(label)*adjustedScale).x)/(rect.size.x-2);
|
||||
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
|
||||
if(sizeRatio>1){
|
||||
adjustedScale.x/=sizeRatio;
|
||||
}
|
||||
}
|
||||
window.DrawStringPropDecal(rect.pos+V(A::DRAW_OFFSET)+rect.size/2-vf2d(game->GetTextSizeProp(label))/2.f*adjustedScale,label,WHITE,adjustedScale);
|
||||
window.DrawStringPropDecal(rect.pos+V(A::DRAW_OFFSET)+rect.size/2-vf2d(labelTextSize)/2.f*adjustedScale,label,WHITE,adjustedScale,rect.size.x);
|
||||
}
|
||||
if(selected){
|
||||
switch(selectionType){
|
||||
|
@ -66,27 +66,25 @@ protected:
|
||||
}
|
||||
inline virtual void DrawDecal(ViewPort&window,bool focused)override{
|
||||
MenuComponent::DrawDecal(window,focused);
|
||||
std::string adjustedText=label;
|
||||
if(!fitToLabel){
|
||||
adjustedText=util::WrapText(game,label,int(rect.size.x),true,{float(scale),float(scale)});
|
||||
}
|
||||
vf2d adjustedScale={scale,scale};
|
||||
vf2d labelTextSize=game->GetTextSizeProp(label,rect.size.x);
|
||||
|
||||
if(fitToLabel){
|
||||
float sizeRatio=((game->GetTextSizeProp(label)*adjustedScale).x)/(rect.size.x-2);
|
||||
float sizeRatio=((labelTextSize*adjustedScale).x)/(rect.size.x-2);
|
||||
if(sizeRatio>1){
|
||||
adjustedScale.x/=sizeRatio;
|
||||
}
|
||||
}
|
||||
|
||||
vf2d drawPos=rect.middle()-vf2d{game->GetTextSizeProp(adjustedText)}*float(adjustedScale.x)/2; //Assume centered.
|
||||
vf2d drawPos=rect.middle()-vf2d{labelTextSize}*float(adjustedScale.x)/2; //Assume centered.
|
||||
if(!centered){
|
||||
drawPos=vf2d{rect.pos.x+2,rect.middle().y-game->GetTextSizeProp(adjustedText).y/2}; //We should at least vertically align here.
|
||||
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
|
||||
}
|
||||
|
||||
if(shadow){
|
||||
window.DrawShadowStringPropDecal(drawPos,adjustedText,WHITE,BLACK,adjustedScale);
|
||||
window.DrawShadowStringPropDecal(drawPos,label,WHITE,BLACK,adjustedScale,rect.size.x);
|
||||
}else{
|
||||
window.DrawStringPropDecal(drawPos,adjustedText,WHITE,adjustedScale);
|
||||
window.DrawStringPropDecal(drawPos,label,WHITE,adjustedScale,rect.size.x);
|
||||
}
|
||||
}
|
||||
};
|
@ -50,7 +50,7 @@ void State_GameRun::OnStateChange(GameState*prevState){
|
||||
Menu::CloseAllMenus();
|
||||
}
|
||||
game->GetPlayer()->SetState(State::NORMAL);
|
||||
port=ViewPort::rectViewPort({0,0},{72,100},{75,100});
|
||||
port=ViewPort::rectViewPort({0,0},{240,240},{24,24});
|
||||
}
|
||||
void State_GameRun::OnUserUpdate(Crawler*game){
|
||||
game->bossDisplayTimer=std::max(0.f,game->bossDisplayTimer-game->GetElapsedTime());
|
||||
@ -76,20 +76,20 @@ void State_GameRun::OnUserUpdate(Crawler*game){
|
||||
}
|
||||
void State_GameRun::Draw(Crawler*game){
|
||||
game->RenderHud();
|
||||
//FontTest(); //Enable to test font coloring.
|
||||
FontTest(); //Enable to test font coloring.
|
||||
}
|
||||
|
||||
void State_GameRun::FontTest(){
|
||||
port.DrawStringDecal({8,8},"#FFFFFFThis is a #000066test of hex");
|
||||
port.DrawStringDecal({8,16},"#FF0000This is a #BFA6F9test of hex");
|
||||
port.DrawStringDecal({8,24},"#00FF00This is a #E9A6F9test of hex");
|
||||
port.DrawStringDecal({8,32},"#0000FFThis is a #F9E8A6test of hex");
|
||||
port.DrawShadowStringDecal({8,40},"#FFFFFFThis is a #000066test of hex");
|
||||
port.DrawShadowStringDecal({8,48},"#FF0000This is a #BFA6F9test of hex");
|
||||
port.DrawShadowStringDecal({8,56},"#00FF00This is a #E9A6F9test of hex");
|
||||
port.DrawShadowStringDecal({8,64},"#0000FFThis is a #F9E8A6test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,72},U"#FFFFFFThis is a #000066test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,80},U"#FF0000This is a #BFA6F9test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,88},U"#00FF00This is a #E9A6F9test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,96},U"#0000FFThis is a #F9E8A6test of hex");
|
||||
port.DrawStringDecal({8,24*0},"#FF0000This is a #BFA6F9test of hex",WHITE,{1,1},72);
|
||||
port.DrawStringDecal({8,24*1},"#00FF00This is a #E9A6F9test of hex",WHITE,{1,1},72);
|
||||
port.DrawStringDecal({8,24*2},"#0000FFThis is a #F9E8A6test of hex",WHITE,{1,1},72);
|
||||
port.DrawShadowStringDecal({8,24*3},"#FFFFFFThis is a #000066test of hex",WHITE,BLACK,{1,1},72);
|
||||
port.DrawShadowStringDecal({8,24*4},"#FF0000This is a #BFA6F9test of hex",WHITE,BLACK,{1,1},72);
|
||||
port.DrawShadowStringPropDecal({8,24*5},"#00FF00This is a #E9A6F9test of hex",WHITE,BLACK,{1,1},72);
|
||||
port.DrawShadowStringPropDecal({8,24*6},"#0000FFThis is a #F9E8A6test of hex",WHITE,BLACK,{1,1},72);
|
||||
/*port.DrawShadowStringDecal(VisualNovel::font,{8,24*7},U"#FFFFFFThis is a #000066test of hex",WHITE,BLACK,{1,1},72);
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,24*8},U"#FF0000This is a #BFA6F9test of hex",WHITE,BLACK,{1,1},72);
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,24*9},U"#00FF00This is a #E9A6F9test of hex",WHITE,BLACK,{1,1},72);
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,24*10},U"#0000FFThis is a #F9E8A6test of hex",WHITE,BLACK,{1,1},72);*/
|
||||
port.drawEdges();
|
||||
}
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 4274
|
||||
#define VERSION_BUILD 4334
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -116,11 +116,11 @@ namespace olc {
|
||||
const vf2d &pos2,
|
||||
Pixel p = WHITE) const;
|
||||
// Draws a multiline string as a decal, with tinting and scaling
|
||||
void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const bool colorOverride=false);
|
||||
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits<float>::max(),const bool colorOverride=false);
|
||||
void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1);
|
||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const float shadowSizeFactor=1);
|
||||
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
|
||||
@ -628,8 +628,12 @@ float olc::ViewPort::directionFromLine(vf2d lineA, vf2d lineB, vf2d point) {
|
||||
- (point.x - lineA.x) * (lineB.y - lineA.y);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
olc::vf2d spos = { 0.0f, 0.0f };
|
||||
void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale, const float width,const bool colorOverride){
|
||||
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||
letters.clear();
|
||||
bool wrappingOccurred=false;
|
||||
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
@ -642,91 +646,35 @@ void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, const std::string& sTe
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
spos.x = 0; spos.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
textCol=BLACK;
|
||||
for(int i=1;i<7;i++){
|
||||
if(i<3){
|
||||
textCol.r*=16;
|
||||
textCol.r+=hexToNumber(sText[index+i]);
|
||||
}else
|
||||
if(i<5){
|
||||
textCol.g*=16;
|
||||
textCol.g+=hexToNumber(sText[index+i]);
|
||||
}else{
|
||||
textCol.b*=16;
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
DrawPartialDecal(pos + spos, pge->GetFontDecal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, textCol);
|
||||
spos.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
struct DecalData{
|
||||
Decal*decal;
|
||||
float expireTime=0.0f;
|
||||
};
|
||||
if(sText.length()==0)return;
|
||||
static std::map<std::u32string,DecalData>garbageCollector;
|
||||
std::u32string key=font.GetFontName()+U"_"+sText;
|
||||
if(!garbageCollector.count(key)){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||
garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE);
|
||||
}
|
||||
garbageCollector[key].expireTime=pge->GetRuntime()+120.0f;
|
||||
std::erase_if(garbageCollector,[&](auto&key){
|
||||
if(key.second.expireTime<pge->GetRuntime()){
|
||||
delete key.second.decal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,col);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
olc::vf2d spos = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
return (c-'A')+10;
|
||||
};
|
||||
for (int skip=0,index=-1;auto c : sText)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
spos.x = 0; spos.y += 8.0f * scale.y;
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
planningMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
@ -753,45 +701,183 @@ void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, const std::string&
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
}
|
||||
if(textCol==WHITE)textCol=col;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
DrawPartialDecal(pos + spos, pge->GetFontDecal(), { float(ox) * 8.0f + float(pge->vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(pge->vFontSpacing[c - 32].y), 8.0f }, scale, textCol);
|
||||
spos.x += float(pge->vFontSpacing[c - 32].y) * scale.x;
|
||||
planningMarker.x += 8.0f * scale.x;
|
||||
if(planningMarker.x>=width){
|
||||
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
}
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
drawingMarker=planningMarker;
|
||||
wrappingOccurred=true;
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
planningMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
letters.emplace_back(c,vf2d{ float(ox) * 8.0f, float(oy) * 8.0f }, vf2d{ 8.0f, 8.0f },colorOverride?col:textCol);
|
||||
}
|
||||
}
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
std::string strippedText=sText;
|
||||
std::erase_if(strippedText,[](char chr){return chr<0;});
|
||||
int skip=0;
|
||||
std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;});
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawStringDecal(pos+vf2d{x,y}, strippedText, shadowCol,scale);
|
||||
}
|
||||
}
|
||||
void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
struct DecalData{
|
||||
Decal*decal;
|
||||
float expireTime=0.0f;
|
||||
};
|
||||
if(sText.length()==0)return;
|
||||
static std::map<std::u32string,DecalData>garbageCollector;
|
||||
std::u32string key=font.GetFontName()+U"_"+sText;
|
||||
if(!garbageCollector.count(key)){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||
garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE);
|
||||
}
|
||||
DrawStringDecal(pos, sText, col,scale);
|
||||
garbageCollector[key].expireTime=pge->GetRuntime()+120.0f;
|
||||
std::erase_if(garbageCollector,[&](auto&key){
|
||||
if(key.second.expireTime<pge->GetRuntime()){
|
||||
delete key.second.decal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,col);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
std::string strippedText=sText;
|
||||
std::erase_if(strippedText,[](char chr){return chr<0;});
|
||||
int skip=0;
|
||||
std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;});
|
||||
void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width,const bool colorOverride){
|
||||
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||
letters.clear();
|
||||
bool wrappingOccurred=false;
|
||||
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
return (c-'A')+10;
|
||||
};
|
||||
for (int skip=0,index=-1;auto c : sText)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
drawingMarker.x += float(pge->vFontSpacing[' ' - 32].y) * scale.x;
|
||||
planningMarker.x += float(pge->vFontSpacing[' ' - 32].y) * scale.x;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c==PixelGameEngine::Reset[0])
|
||||
{
|
||||
textCol=col;
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
textCol=BLACK;
|
||||
for(int i=1;i<7;i++){
|
||||
if(i<3){
|
||||
textCol.r*=16;
|
||||
textCol.r+=hexToNumber(sText[index+i]);
|
||||
}else
|
||||
if(i<5){
|
||||
textCol.g*=16;
|
||||
textCol.g+=hexToNumber(sText[index+i]);
|
||||
}else{
|
||||
textCol.b*=16;
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
}
|
||||
if(textCol==WHITE)textCol=col;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
planningMarker.x += float(pge->vFontSpacing[c - 32].y) * scale.x;
|
||||
if(planningMarker.x>=width){
|
||||
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
}
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
drawingMarker=planningMarker;
|
||||
wrappingOccurred=true;
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
planningMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
}
|
||||
letters.emplace_back(c,vf2d{ float(ox) * 8.0f + float(pge->vFontSpacing[c - 32].x), float(oy) * 8.0f }, vf2d{ float(pge->vFontSpacing[c - 32].y), 8.0f },colorOverride?col:textCol);
|
||||
}
|
||||
}
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, pge->GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += float(pge->vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawStringPropDecal(pos+vf2d{x,y}, strippedText, shadowCol,scale);
|
||||
DrawStringDecal(pos+vf2d{x,y}, sText, shadowCol,scale,width,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawStringPropDecal(pos, sText, col,scale);
|
||||
DrawStringDecal(pos, sText, col,scale,width);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float width,const float shadowSizeFactor){
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawStringPropDecal(pos+vf2d{x,y}, sText, shadowCol,scale,width,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawStringPropDecal(pos, sText, col,scale,width);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
|
@ -385,6 +385,7 @@ return 0;
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <iostream>
|
||||
#include <streambuf>
|
||||
#include <sstream>
|
||||
@ -747,9 +748,6 @@ namespace olc
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// O------------------------------------------------------------------------------O
|
||||
// | olc::ResourcePack - A virtual scrambled filesystem to pack your assets into |
|
||||
// O------------------------------------------------------------------------------O
|
||||
@ -968,6 +966,14 @@ namespace olc
|
||||
// O------------------------------------------------------------------------------O
|
||||
class PixelGameEngine
|
||||
{
|
||||
struct StringDecalData{
|
||||
char c;
|
||||
vf2d sourcePos;
|
||||
vf2d sourceSize;
|
||||
Pixel col;
|
||||
StringDecalData(char c,vf2d sourcePos,vf2d sourceSize,Pixel col)
|
||||
:c(c),sourcePos(sourcePos),sourceSize(sourceSize),col(col){};
|
||||
};
|
||||
public:
|
||||
PixelGameEngine();
|
||||
virtual ~PixelGameEngine();
|
||||
@ -1114,8 +1120,8 @@ namespace olc
|
||||
void DrawShadowString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
void DrawShadowStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
olc::vi2d GetTextSize(const std::string& s);
|
||||
olc::vi2d GetTextSizeProp(const std::string& s);
|
||||
olc::vi2d GetTextSize(std::string_view s,const int width=std::numeric_limits<int>::max());
|
||||
olc::vi2d GetTextSizeProp(std::string_view s,const int width=std::numeric_limits<int>::max());
|
||||
void DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
void DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1);
|
||||
|
||||
@ -1141,9 +1147,9 @@ namespace olc
|
||||
void DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||
void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
|
||||
// Draws a multiline string as a decal, with tiniting and scaling
|
||||
void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const bool colorOverride=false);
|
||||
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits<float>::max(),const bool colorOverride=false);
|
||||
void DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
@ -3344,9 +3350,13 @@ namespace olc
|
||||
void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint)
|
||||
{ DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint); }
|
||||
|
||||
void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale)
|
||||
void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width,const bool colorOverride)
|
||||
{
|
||||
olc::vf2d spos = { 0.0f, 0.0f };
|
||||
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||
letters.clear();
|
||||
bool wrappingOccurred=false;
|
||||
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
@ -3359,76 +3369,41 @@ namespace olc
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
spos.x = 0; spos.y += 8.0f * scale.y;
|
||||
if(c==' '||c=='\t'){
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={charToColor[c].r,charToColor[c].g,charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
textCol=BLACK;
|
||||
for(int i=1;i<7;i++){
|
||||
if(i<3){
|
||||
textCol.r*=16;
|
||||
textCol.r+=hexToNumber(sText[index+i]);
|
||||
}else
|
||||
if(i<5){
|
||||
textCol.g*=16;
|
||||
textCol.g+=hexToNumber(sText[index+i]);
|
||||
}else{
|
||||
textCol.b*=16;
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
DrawPartialDecal(pos + spos, fontRenderable.Decal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, textCol);
|
||||
spos.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PixelGameEngine::DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale)
|
||||
{
|
||||
olc::vf2d spos = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
return (c-'A')+10;
|
||||
};
|
||||
for (int skip=0,index=-1;auto c : sText)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
spos.x = 0; spos.y += 8.0f * scale.y;
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
planningMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={charToColor[c].r,charToColor[c].g,charToColor[c].b,col.a};
|
||||
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c==Reset[0])
|
||||
else if (c==PixelGameEngine::Reset[0])
|
||||
{
|
||||
textCol=col;
|
||||
}
|
||||
@ -3449,15 +3424,140 @@ namespace olc
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
}
|
||||
if(textCol==WHITE)textCol=col;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
DrawPartialDecal(pos + spos, fontRenderable.Decal(), { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, textCol);
|
||||
spos.x += float(vFontSpacing[c - 32].y) * scale.x;
|
||||
planningMarker.x += 8.0f * scale.x;
|
||||
if(planningMarker.x>=width){
|
||||
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
}
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
drawingMarker=planningMarker;
|
||||
wrappingOccurred=true;
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
planningMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
letters.emplace_back(c,vf2d{ float(ox) * 8.0f, float(oy) * 8.0f }, vf2d{ 8.0f, 8.0f },colorOverride?col:textCol);
|
||||
}
|
||||
}
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, fontRenderable.Decal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
|
||||
void PixelGameEngine::DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale, const float width,const bool colorOverride)
|
||||
{
|
||||
static std::vector<PixelGameEngine::StringDecalData>letters;
|
||||
letters.clear();
|
||||
bool wrappingOccurred=false;
|
||||
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
return (c-'A')+10;
|
||||
};
|
||||
for (int skip=0,index=-1;auto c : sText)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
drawingMarker.x += float(vFontSpacing[' ' - 32].y) * scale.x;
|
||||
planningMarker.x += float(vFontSpacing[' ' - 32].y) * scale.x;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
drawingMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
planningMarker.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c==PixelGameEngine::Reset[0])
|
||||
{
|
||||
textCol=col;
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
textCol=BLACK;
|
||||
for(int i=1;i<7;i++){
|
||||
if(i<3){
|
||||
textCol.r*=16;
|
||||
textCol.r+=hexToNumber(sText[index+i]);
|
||||
}else
|
||||
if(i<5){
|
||||
textCol.g*=16;
|
||||
textCol.g+=hexToNumber(sText[index+i]);
|
||||
}else{
|
||||
textCol.b*=16;
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
}
|
||||
if(textCol==WHITE)textCol=col;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
planningMarker.x += float(vFontSpacing[c - 32].y) * scale.x;
|
||||
if(planningMarker.x>=width){
|
||||
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
letters.clear();
|
||||
}
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f * scale.y;
|
||||
drawingMarker=planningMarker;
|
||||
wrappingOccurred=true;
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
planningMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
}
|
||||
letters.emplace_back(c,vf2d{ float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, vf2d{ float(vFontSpacing[c - 32].y), 8.0f },colorOverride?col:textCol);
|
||||
}
|
||||
}
|
||||
for(PixelGameEngine::StringDecalData&letter:letters){
|
||||
DrawPartialDecal(pos + drawingMarker, GetFontDecal(), letter.sourcePos, letter.sourceSize, scale, letter.col);
|
||||
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale.x;
|
||||
}
|
||||
}
|
||||
|
||||
void PixelGameEngine::DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
@ -3664,30 +3764,76 @@ namespace olc
|
||||
DrawRotatedStringPropDecal(pos, sText,fAngle,center,col,scale);
|
||||
}
|
||||
|
||||
olc::vi2d PixelGameEngine::GetTextSize(const std::string& s)
|
||||
olc::vi2d PixelGameEngine::GetTextSize(std::string_view s,const int width)
|
||||
{
|
||||
olc::vi2d size = { 0,1 };
|
||||
olc::vi2d pos = { 0,1 };
|
||||
for (int skip=0;auto c : s)
|
||||
int lettersWidth=0;
|
||||
int maxWidth=0;
|
||||
bool wrappingOccurred=false;
|
||||
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||
for (int skip=0,index=-1;auto c : s)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
drawingMarker.x+=lettersWidth;
|
||||
lettersWidth=0;
|
||||
wrappingOccurred=false;
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
wrappingOccurred=false;
|
||||
maxWidth=std::max(maxWidth,int(drawingMarker.x));
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n') { pos.y++; pos.x = 0; }
|
||||
else if (c == '\t') { pos.x += nTabSizeInSpaces; }
|
||||
else if(c<0)continue;
|
||||
if (c == '\n')
|
||||
{
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
drawingMarker.x += 8.0f;
|
||||
planningMarker.x += 8.0f;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
drawingMarker.x += 8.0f * float(nTabSizeInSpaces);
|
||||
planningMarker.x += 8.0f * float(nTabSizeInSpaces);
|
||||
}
|
||||
else if (c>=-128&&c<-105||c==PixelGameEngine::Reset[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
continue;
|
||||
}
|
||||
else pos.x++;
|
||||
size.x = std::max(size.x, pos.x);
|
||||
size.y = std::max(size.y, pos.y);
|
||||
else
|
||||
{
|
||||
planningMarker.x += 8.0f;
|
||||
if(planningMarker.x>=width){
|
||||
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||
drawingMarker.x+=lettersWidth;
|
||||
lettersWidth=0;
|
||||
maxWidth=std::max(maxWidth,int(drawingMarker.x));
|
||||
}
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f;
|
||||
drawingMarker=planningMarker;
|
||||
wrappingOccurred=true;
|
||||
planningMarker.x+=lettersWidth;
|
||||
}
|
||||
lettersWidth+=8.0f;
|
||||
}
|
||||
}
|
||||
return size * 8;
|
||||
drawingMarker.x += lettersWidth;
|
||||
maxWidth=std::max(maxWidth,int(drawingMarker.x));
|
||||
return {maxWidth,int(planningMarker.y+8)};
|
||||
}
|
||||
|
||||
void PixelGameEngine::DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale)
|
||||
@ -3779,32 +3925,76 @@ namespace olc
|
||||
SetPixelMode(m);
|
||||
}
|
||||
|
||||
olc::vi2d PixelGameEngine::GetTextSizeProp(const std::string& s)
|
||||
olc::vi2d PixelGameEngine::GetTextSizeProp(std::string_view s,const int width)
|
||||
{
|
||||
olc::vi2d size = { 0,1 };
|
||||
olc::vi2d pos = { 0,1 };
|
||||
for (int skip=0;auto c : s)
|
||||
int lettersWidth=0;
|
||||
int maxWidth=0;
|
||||
bool wrappingOccurred=false;
|
||||
olc::vf2d planningMarker = { 0.0f, 0.0f };
|
||||
olc::vf2d drawingMarker = { 0.0f, 0.0f };
|
||||
for (int skip=0,index=-1;auto c : s)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c==' '||c=='\t'){
|
||||
drawingMarker.x+=lettersWidth;
|
||||
lettersWidth=0;
|
||||
wrappingOccurred=false;
|
||||
maxWidth=std::max(maxWidth,int(drawingMarker.x));
|
||||
}
|
||||
if(wrappingOccurred){
|
||||
if(c!=' '&&c!='\t'){
|
||||
wrappingOccurred=false;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n') { pos.y += 1; pos.x = 0; }
|
||||
else if (c == '\t') { pos.x += nTabSizeInSpaces * 8; }
|
||||
else if(c<0)continue;
|
||||
if (c == '\n')
|
||||
{
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
drawingMarker.x += vFontSpacing[c-32].y;
|
||||
planningMarker.x += vFontSpacing[c-32].y;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
drawingMarker.x += 8.0f * float(nTabSizeInSpaces);
|
||||
planningMarker.x += 8.0f * float(nTabSizeInSpaces);
|
||||
}
|
||||
else if (c>=-128&&c<-105||c==PixelGameEngine::Reset[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
continue;
|
||||
}
|
||||
else pos.x += vFontSpacing[c - 32].y;
|
||||
size.x = std::max(size.x, pos.x);
|
||||
size.y = std::max(size.y, pos.y);
|
||||
else
|
||||
{
|
||||
planningMarker.x += vFontSpacing[c-32].y;
|
||||
if(planningMarker.x>=width){
|
||||
if(drawingMarker.x==0){ //The text has overflowed a full line, so we have to dump the line.
|
||||
drawingMarker.x+=lettersWidth;
|
||||
lettersWidth=0;
|
||||
maxWidth=std::max(maxWidth,int(drawingMarker.x));
|
||||
}
|
||||
planningMarker.x = 0; planningMarker.y += 8.0f;
|
||||
drawingMarker=planningMarker;
|
||||
wrappingOccurred=true;
|
||||
planningMarker.x+=lettersWidth;
|
||||
}
|
||||
lettersWidth+=vFontSpacing[c-32].y;
|
||||
}
|
||||
}
|
||||
|
||||
size.y *= 8;
|
||||
return size;
|
||||
drawingMarker.x += lettersWidth;
|
||||
maxWidth=std::max(maxWidth,int(drawingMarker.x));
|
||||
return {maxWidth,int(planningMarker.y+8)};
|
||||
}
|
||||
|
||||
void PixelGameEngine::DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale)
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user