diff options
author | Eugene Sandulenko | 2018-12-25 12:37:23 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-12-25 12:37:23 +0100 |
commit | 1f6727eab85c8f544718deba6a820e1b71ee5c93 (patch) | |
tree | 5d86c27377baa8fac79ced213a8fe4b21a3a1344 /devtools/blade_runner/subtitles/fontCreator/fonFileLib.py | |
parent | b6e93680f449b6d988aeceac0c0a58218b2992d0 (diff) | |
download | scummvm-rg350-1f6727eab85c8f544718deba6a820e1b71ee5c93.tar.gz scummvm-rg350-1f6727eab85c8f544718deba6a820e1b71ee5c93.tar.bz2 scummvm-rg350-1f6727eab85c8f544718deba6a820e1b71ee5c93.zip |
DEVTOOLS: Rename blade_runner to create_bladerunner
Diffstat (limited to 'devtools/blade_runner/subtitles/fontCreator/fonFileLib.py')
-rw-r--r-- | devtools/blade_runner/subtitles/fontCreator/fonFileLib.py | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/devtools/blade_runner/subtitles/fontCreator/fonFileLib.py b/devtools/blade_runner/subtitles/fontCreator/fonFileLib.py deleted file mode 100644 index c523162950..0000000000 --- a/devtools/blade_runner/subtitles/fontCreator/fonFileLib.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- -# -import os, sys, shutil -import struct -from struct import * -import Image - -my_module_version = "0.50" -my_module_name = "fonFileLib" - - -class FonHeader: - maxEntriesInTableOfDetails = -1 # this is probably always the number of entries in table of details, but it won't work for the corrupted TAHOMA18.FON file - maxGlyphWidth = -1 # in pixels - maxGlyphHeight = -1 # in pixels - graphicSegmentByteSize = -1 # Graphic segment byte size - - def __init__(self): - return - - -class fonFile: - m_header = FonHeader() - - simpleFontFileName = "GENERIC.FON" - realNumOfCharactersInImageSegment = 0 # this is used for the workaround for the corrupted TAHOME18.FON - nonEmptyCharacters = 0 - - glyphDetailEntriesLst = [] # list of 5-value tuples. Tuple values are (X-offset, Y-offset, Width, Height, Offset in Graphics segment) - glyphPixelData = None # buffer of pixel data for glyphs - - def __init__(self): - del self.glyphDetailEntriesLst[:] - self.glyphPixelData = None # buffer of pixel data for glyphs - self.simpleFontFileName = "GENERIC.FON" - self.realNumOfCharactersInImageSegment = 0 # this is used for the workaround for the corrupted TAHOME18.FON - self.nonEmptyCharacters = 0 - - return - - def loadFonFile(self, fonBytesBuff, maxLength, fonFileName): - self.simpleFontFileName = fonFileName - - - offsInFonFile = 0 - localLstOfDataOffsets = [] - del localLstOfDataOffsets[:] - # - # parse FON file fields for header - # - try: - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - self.header().maxEntriesInTableOfDetails = tmpTuple[0] - offsInFonFile += 4 - - if self.simpleFontFileName == 'TAHOMA18.FON': # deal with corrupted original 'TAHOMA18.FON' file - self.realNumOfCharactersInImageSegment = 176 - print "SPECIAL CASE. WORKAROUND FOR CORRUPTED %s FILE. Only %d characters supported!" % (self.simpleFontFileName, self.realNumOfCharactersInImageSegment) - else: - self.realNumOfCharactersInImageSegment = self.header().maxEntriesInTableOfDetails - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - self.header().maxGlyphWidth = tmpTuple[0] - offsInFonFile += 4 - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - self.header().maxGlyphHeight = tmpTuple[0] - offsInFonFile += 4 - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - self.header().graphicSegmentByteSize = tmpTuple[0] - offsInFonFile += 4 - - print "FON Header Info: " - print "Num of entries: %d\tGlyph max-Width: %d\tGlyph max-Height: %d\tGraphic Segment size %d" % (self.header().maxEntriesInTableOfDetails, self.header().maxGlyphWidth, self.header().maxGlyphHeight, self.header().graphicSegmentByteSize) - #print "Num of entries: %d\tGlyph max-Width: %d\tGlyph max-Height: %d\tGraphic Segment size %d" % (self.realNumOfCharactersInImageSegment, self.header().maxGlyphWidth, self.header().maxGlyphHeight, self.header().graphicSegmentByteSize) - # - # Glyph details table (each entry is 5 unsigned integers == 5*4 = 20 bytes) - # For most characters, their ASCII value + 1 is the index of their glyph's entry in the details table. The 0 entry of this table is reserved - # - #tmpXOffset, tmpYOffset, tmpWidth, tmpHeight, tmpDataOffset - print "FON glyph details table: " - for idx in range(0, self.realNumOfCharactersInImageSegment): - tmpTuple = struct.unpack_from('i', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - tmpXOffset = tmpTuple[0] - offsInFonFile += 4 - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - tmpYOffset = tmpTuple[0] - offsInFonFile += 4 - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - tmpWidth = tmpTuple[0] - offsInFonFile += 4 - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - tmpHeight = tmpTuple[0] - offsInFonFile += 4 - - tmpTuple = struct.unpack_from('I', fonBytesBuff, offsInFonFile) # unsigned integer 4 bytes - tmpDataOffset = tmpTuple[0] - offsInFonFile += 4 - - if tmpWidth == 0 or tmpHeight == 0: - print "Index: %d\t UNUSED *****************************************************************" % (idx) - else: - self.nonEmptyCharacters += 1 - print "Index: %d\txOffs: %d\tyOffs: %d\twidth: %d\theight: %d\tdataOffs: %d" % (idx, tmpXOffset, tmpYOffset, tmpWidth, tmpHeight, tmpDataOffset) - if tmpDataOffset not in localLstOfDataOffsets: - localLstOfDataOffsets.append(tmpDataOffset) - else: - # This never happens in the original files. Offsets are "re-used" but not really because it happens only for empty (height = 0) characters which all seem to point to the next non-empty character - print "Index: %d\t RE-USING ANOTHER GLYPH *****************************************************************" % (idx) - - self.glyphDetailEntriesLst.append( ( tmpXOffset, tmpYOffset, tmpWidth, tmpHeight, tmpDataOffset) ) - - offsInFonFile = (4 * 4) + (self.header().maxEntriesInTableOfDetails * 5 * 4) # we need the total self.header().maxEntriesInTableOfDetails here and not self.realNumOfCharactersInImageSegment - self.glyphPixelData = fonBytesBuff[offsInFonFile:] - return True - except: - print "Loading failure!" - raise - return False - - def outputFonToPNG(self): - targWidth = 0 - targHeight = 0 - paddingFromTopY = 2 - paddingBetweenGlyphsX = 10 - - - if len(self.glyphDetailEntriesLst) == 0 or (len(self.glyphDetailEntriesLst) != self.realNumOfCharactersInImageSegment and len(self.glyphDetailEntriesLst) != self.header().maxEntriesInTableOfDetails) : - print "Error. Fon file load process did not complete correctly. Missing important data in structures. Cannot output image!" - return - - # TODO asdf refine this code here. the dimensions calculation is very crude for now - if self.header().maxGlyphWidth > 0 : - targWidth = (self.header().maxGlyphWidth + paddingBetweenGlyphsX) * (self.realNumOfCharactersInImageSegment + 1) - else: - targWidth = 1080 - - # TODO asdf refine this code here. the dimensions calculation is very crude for now - if self.header().maxGlyphHeight > 0 : - targHeight = self.header().maxGlyphHeight * 2 - else: - targHeight = 480 - - imTargetGameFont = Image.new("RGBA",(targWidth, targHeight), (0,0,0,0)) - #print imTargetGameFont.getbands() - # - # Now fill in the image segment - # Fonts in image segment are stored in pixel colors from TOP to Bottom, Left to Right per GLYPH. - # Each pixel is 16 bit (2 bytes). Highest bit seems to determine transparency (on/off flag). - # There seem to be 5 bits per RGB channel and the value is the corresponding 8bit value (from the 24 bit pixel color) shifting out (right) the 3 LSBs - # First font image is the special character (border of top row and left column) - color of font pixels should be "0x7FFF" for filled and "0x8000" for transparent - drawIdx = 0 - drawIdxDeductAmount = 0 - for idx in range(0, self.realNumOfCharactersInImageSegment): - # TODO check for size > 0 for self.glyphPixelData - # TODO mark glyph OUTLINES? (optional by switch) - (glyphXoffs, glyphYoffs, glyphWidth, glyphHeight, glyphDataOffs) = self.glyphDetailEntriesLst[idx] - glyphDataOffs = glyphDataOffs * 2 - #print idx, glyphDataOffs - currX = 0 - currY = 0 - if (glyphWidth == 0 or glyphHeight == 0): - drawIdxDeductAmount += 1 - drawIdx = idx - drawIdxDeductAmount - - for colorIdx in range(0, glyphWidth*glyphHeight): - tmpTuple = struct.unpack_from('H', self.glyphPixelData, glyphDataOffs) # unsigned short 2 bytes - pixelColor = tmpTuple[0] - glyphDataOffs += 2 - -# if pixelColor > 0x8000: -# print "WEIRD CASE" # NEVER HAPPENS - TRANSPARENCY IS ON/OFF. There's no grades of transparency - rgbacolour = (0,0,0,0) - if pixelColor == 0x8000: - rgbacolour = (0,0,0,0) # alpha: 0.0 fully transparent - else: - tmp8bitR1 = ( (pixelColor >> 10) ) << 3 - tmp8bitG1 = ( (pixelColor & 0x3ff) >> 5 ) << 3 - tmp8bitB1 = ( (pixelColor & 0x1f) ) << 3 - rgbacolour = (tmp8bitR1,tmp8bitG1,tmp8bitB1, 255) # alpha: 1.0 fully opaque - #rgbacolour = (255,255,255, 255) # alpha: 1.0 fully opaque - - if currX == glyphWidth: - currX = 0 - currY += 1 - - imTargetGameFont.putpixel(( (drawIdx + 1) * (self.header().maxGlyphWidth + paddingBetweenGlyphsX ) + currX, paddingFromTopY + glyphYoffs + currY), rgbacolour) - currX += 1 - - imTargetGameFont.save(os.path.join('.', self.simpleFontFileName + ".PNG"), "PNG") - - def header(self): - return self.m_header -# -# -# -if __name__ == '__main__': - # main() - print "Running %s as main module" % (my_module_name) - # assumes a file of name TAHOMA24.FON in same directory - inFONFile = None - #inFONFileName = 'TAHOMA24.FON' # USED IN CREDIT END-TITLES and SCORERS BOARD AT POLICE STATION - #inFONFileName = 'TAHOMA18.FON' # USED IN CREDIT END-TITLES - #inFONFileName = '10PT.FON' # BLADE RUNNER UNUSED FONT? - #inFONFileName = 'KIA6PT.FON' # BLADE RUNNER MAIN FONT - inFONFileName = 'SUBTLS_E.FON' # Subtitles font custom - - errorFound = False - try: - print "Opening %s" % (inFONFileName) - inFONFile = open(os.path.join('.',inFONFileName), 'rb') - except: - errorFound = True - print "Unexpected error:", sys.exc_info()[0] - raise - if not errorFound: - allOfFonFileInBuffer = inFONFile.read() - fonFileInstance = fonFile() - if (fonFileInstance.loadFonFile(allOfFonFileInBuffer, len(allOfFonFileInBuffer), inFONFileName)): - print "FON file loaded successfully!" - fonFileInstance.outputFonToPNG() - else: - print "Error while loading FON file!" - inFONFile.close() -else: - #debug - #print "Running %s imported from another module" % (my_module_name) - pass
\ No newline at end of file |