pixelocr/pixelocr/glyphdb.py
2014-09-04 17:46:48 +02:00

129 lines
3.6 KiB
Python

# Copyright (C) 2014 Andrey Golovizin
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
import pickle
from collections import OrderedDict, namedtuple
from datetime import datetime
from os import path
from .utils import cached_property
from .image import Image
Style = namedtuple('Style', ['color', 'bold', 'italic'])
class GlyphData(object):
def __init__(self, image_data, elevation, text, bold=False, italic=False, date_added=None):
self.image_data = image_data
self.elevation = elevation
self.text = text
self.bold = bold
self.italic = italic
self.date_added = datetime.now() if date_added is None else date_added
@classmethod
def from_glyph(cls, glyph, *args, **kwargs):
return cls(glyph.image.serialize(), glyph.elevation, *args, **kwargs)
@property
def color(self):
return self.image.color
@property
def style(self):
return Style(self.color, self.bold, self.italic)
@cached_property
def image(self):
return Image.deserialize(self.image_data)
def serialize(self):
return (
self.image_data,
self.elevation,
self.text,
self.bold,
self.italic,
self.date_added,
)
@classmethod
def deserialize(cls, args):
return cls(*args)
class WhitespaceData(GlyphData):
color = (255, 255, 255) # FIXME support non-white background
def __init__(self, text):
super().__init__(None, None, text, bold=False, italic=False)
SPACE = WhitespaceData(' ')
NEWLINE = WhitespaceData('\n')
class GlyphDB(object):
def __init__(self, filename):
self.filename = filename
self._dict = OrderedDict()
if path.isfile(self.filename):
self.load()
def _key_from_glyph(self, glyph):
return (glyph.image.serialize(), glyph.elevation)
def _key_from_data(self, data):
return (data.image_data, data.elevation)
def __getitem__(self, glyph):
key = self._key_from_glyph(glyph)
return self._dict[key]
def add_glyph(self, glyph, text, bold=False, italic=False):
data = GlyphData.from_glyph(glyph, text, bold=bold, italic=italic)
key = self._key_from_glyph(glyph)
self._dict[key] = data
return data
def add(self, data):
key = self._key_from_data(data)
self._dict[key] = data
def remove(self, data):
key = self._key_from_data(data)
del self._dict[key]
def keys(self):
return self._dict.keys()
def items(self):
return self._dict.items()
def values(self):
return self._dict.values()
def load(self):
with open(self.filename, 'rb') as fileobj:
data = pickle.load(fileobj)
for item in data:
self.add(GlyphData.deserialize(item))
def save(self):
data = [data.serialize() for data in self.values()]
with open(self.filename, 'wb') as fileobj:
pickle.dump(data, fileobj)