Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
solemnwarning committed Apr 14, 2024
1 parent dad67d1 commit 6aff7b5
Show file tree
Hide file tree
Showing 10 changed files with 887 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -378,6 +378,7 @@ APP_OBJS := \
src/FileWriter.$(BUILD_TYPE).o \
src/FillRangeDialog.$(BUILD_TYPE).o \
src/FixedSizeValueRegion.$(BUILD_TYPE).o \
src/HighlightColourMap.$(BUILD_TYPE).o \
src/HSVColour.$(BUILD_TYPE).o \
src/IntelHexExport.$(BUILD_TYPE).o \
src/IntelHexImport.$(BUILD_TYPE).o \
Expand Down Expand Up @@ -471,6 +472,7 @@ TEST_OBJS := \
src/FileWriter.$(BUILD_TYPE).o \
src/FillRangeDialog.$(BUILD_TYPE).o \
src/FixedSizeValueRegion.$(BUILD_TYPE).o \
src/HighlightColourMap.$(BUILD_TYPE).o \
src/HSVColour.$(BUILD_TYPE).o \
src/IntelHexExport.$(BUILD_TYPE).o \
src/IntelHexImport.$(BUILD_TYPE).o \
Expand Down Expand Up @@ -515,6 +517,7 @@ TEST_OBJS := \
tests/endian_conv.o \
tests/FastRectangleFiller.o \
tests/FileWriter.o \
tests/HighlightColourMap.o \
tests/HSVColour.o \
tests/IntelHexExport.o \
tests/IntelHexImport.o \
Expand Down
291 changes: 291 additions & 0 deletions src/HighlightColourMap.cpp
@@ -0,0 +1,291 @@
/* Reverse Engineer's Hex Editor
* Copyright (C) 2024 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "HighlightColourMap.hpp"
#include "HSVColour.hpp"
#include "util.hpp"

REHex::HighlightColourMap REHex::HighlightColourMap::defaults()
{
HighlightColourMap map;

for(size_t i = 0; i < DEFAULT_NUM; ++i)
{
auto it = map.add();
assert(it->first == i);
}

return map;
}

// REHex::HighlightColourMap::HighlightColourMap(const wxConfigBase *config)

REHex::HighlightColourMap REHex::HighlightColourMap::from_json(const json_t *json)
{
HighlightColourMap map;

if(!json_is_array(json))
{
throw std::invalid_argument("Expected a JSON array (highlight array)");
}

size_t index;
json_t *value;

json_array_foreach(json, index, value)
{
if(!json_is_object(value))
{
throw std::invalid_argument("Expected a JSON object (highlight object)");
}

json_t *js_index = json_object_get(value, "index");
json_t *js_primary_colour = json_object_get(value, "primary_colour");
json_t *js_secondary_colour = json_object_get(value, "secondary_colour");
json_t *js_label = json_object_get(value, "label");

if(!json_is_integer(js_index))
{
throw std::invalid_argument("Expected a JSON integer (highlight index)");
}

int v_index = json_integer_value(js_index);
if(v_index < 0 || (size_t)(v_index) >= MAX_NUM)
{
throw std::invalid_argument("Highlight index out of range");
}

HighlightColour hc = make_default_highlight(v_index);

wxColour colour_from_json(const json_t *json);
json_t *colour_to_json(const wxColour &colour);

if(js_primary_colour != NULL)
{
hc.primary_colour = colour_from_json(js_primary_colour);
hc.primary_colour_is_default = false;
}

if(js_secondary_colour != NULL)
{
hc.secondary_colour = colour_from_json(js_secondary_colour);
hc.secondary_colour_is_default = false;
}

if(js_label != NULL)
{
if(!json_is_string(js_label))
{
throw std::invalid_argument("Expected a JSON string (highlight label)");
}

hc.label = json_string_value(js_label);
hc.label_is_default = false;
}

if(map.colours.find(v_index) != map.colours.end())
{
throw std::invalid_argument("Duplicate index in highlights array");
}

map.colours.insert(std::make_pair(v_index, hc));
}

return map;
}

json_t *REHex::HighlightColourMap::to_json() const
{
json_t *json = json_array();
if(json == NULL)
{
json_decref(json);
throw std::bad_alloc();
}

for(auto c = colours.begin(); c != colours.end(); ++c)
{
json_t *elem = json_object();
if(
json_array_append_new(json, elem) == -1
|| (!(c->second.primary_colour_is_default) && json_object_set_new(elem, "primary_colour", colour_to_json(c->second.primary_colour)) == -1)
|| (!(c->second.secondary_colour_is_default) && json_object_set_new(elem, "secondary_colour", colour_to_json(c->second.primary_colour)) == -1)
|| (!(c->second.label_is_default) && json_object_set_new(elem, "primary_colour", json_string(c->second.label.c_str())) == -1))
{
json_decref(json);
throw std::bad_alloc();
}
}

return json;
}

REHex::HighlightColourMap::iterator REHex::HighlightColourMap::add()
{
for(size_t i = 0; i < MAX_NUM; ++i)
{
if(colours.find(i) == colours.end())
{
return colours.insert(std::make_pair(i, make_default_highlight(i))).first;
}
}

return end();
}

void REHex::HighlightColourMap::erase(size_t highlight_idx)
{
colours.erase(highlight_idx);
}

void REHex::HighlightColourMap::erase(const const_iterator &it)
{
colours.erase(it);
}

size_t REHex::HighlightColourMap::size() const
{
return colours.size();
}

REHex::HighlightColourMap::iterator REHex::HighlightColourMap::find(size_t highlight_idx)
{
return colours.find(highlight_idx);
}

REHex::HighlightColourMap::const_iterator REHex::HighlightColourMap::find(size_t highlight_idx) const
{
return colours.find(highlight_idx);
}

REHex::HighlightColourMap::iterator REHex::HighlightColourMap::begin()
{
return colours.begin();
}

REHex::HighlightColourMap::iterator REHex::HighlightColourMap::end()
{
return colours.end();
}

REHex::HighlightColourMap::const_iterator REHex::HighlightColourMap::begin() const
{
return colours.begin();
}

REHex::HighlightColourMap::const_iterator REHex::HighlightColourMap::end() const
{
return colours.end();
}

REHex::HighlightColourMap::HighlightColour &REHex::HighlightColourMap::operator[](size_t highlight_idx)
{
auto it = colours.find(highlight_idx);
if(it == colours.end())
{
it = colours.insert(std::make_pair(highlight_idx, make_default_highlight(highlight_idx))).first;
}

return it->second;
}

// void REHex::HighlightColourMap::save(wxConfigBase *config);

REHex::HighlightColourMap::HighlightColour REHex::HighlightColourMap::make_default_highlight(size_t highlight_idx)
{
HighlightColour hc;

switch(highlight_idx)
{
case 0: /* White on Red */
hc.primary_colour = wxColour(0xFF, 0x00, 0x00);
hc.secondary_colour = wxColour(0xFF, 0xFF, 0xFF);
hc.label = "Red";

break;

case 1: /* White on Orange */
hc.primary_colour = wxColour(0xFE, 0x63, 0x00);
hc.secondary_colour = wxColour(0xFF, 0xFF, 0xFF);
hc.label = "Orange";

break;

case 2: /* Black on Yellow */
hc.primary_colour = wxColour(0xFC, 0xFF, 0x00);
hc.secondary_colour = wxColour(0x00, 0x00, 0x00);
hc.label = "Yellow";
break;

case 3: /* Black on Green */
hc.primary_colour = wxColour(0x02, 0xFE, 0x07);
hc.secondary_colour = wxColour(0x00, 0x00, 0x00);
hc.label = "Green";

break;

case 4: /* White on Violet */
hc.primary_colour = wxColour(0xFD, 0x00, 0xFF);
hc.secondary_colour = wxColour(0xFF, 0xFF, 0xFF);
hc.label = "Violet";

break;

case 5: /* White on Grey */
hc.primary_colour = wxColour(0x6A, 0x63, 0x6F);
hc.secondary_colour = wxColour(0xFF, 0xFF, 0xFF);
hc.label = "Grey";

break;

default:
{
std::vector<float> existing_primary_hues;
existing_primary_hues.reserve(highlight_idx);

for(size_t i = 0; i < highlight_idx && i < 6; ++i)
{
HighlightColour i_hc = make_default_highlight(i);
HSVColour primary_colour_hsv = HSVColour(i_hc.primary_colour);

existing_primary_hues.push_back(primary_colour_hsv.h);
}

for(size_t i = 6; i <= highlight_idx; ++i)
{
float next_primary_hue, next_primary_hue_diff;
std::tie(next_primary_hue, next_primary_hue_diff) = HSVColour::pick_contrasting_hue(existing_primary_hues);

existing_primary_hues.push_back(next_primary_hue);
}

HSVColour primary_colour_hsv(existing_primary_hues.back(), 1.0f, 1.0f);

hc.primary_colour = primary_colour_hsv.to_rgb();
hc.secondary_colour = wxColour(0x00, 0x00, 0x00);
hc.label = "Highlight " + std::to_string(highlight_idx + 1);

break;
}
}

hc.primary_colour_is_default = true;
hc.secondary_colour_is_default = true;
hc.label_is_default = true;

return hc;
}

0 comments on commit 6aff7b5

Please sign in to comment.