示例#1
0
 public function actionIndex()
 {
     $modelff = new FileRead();
     if (isset($_POST['TmpXml'])) {
         $model = $_POST['TmpXml'];
         $res = $this->writesimple($model);
         $this->render('result', array('model' => $res));
     } else {
         if (isset($_POST['FileRead'])) {
             $modelff->attributes = $_POST['FileRead'];
             if (!$modelff->validate()) {
                 $this->render('fform', array('model' => $modelff));
                 return;
             }
             $modelff->image = CUploadedFile::getInstance($modelff, 'image');
             if (is_object($modelff->image)) {
                 //				$path=Yii::app()->params['load_xml'];
                 $path = 'docs/go.csv';
                 $modelff->image->saveAs($path);
             }
             $thefile = Yii::app()->params['load_csv'];
             $ii = $this->readsimple($thefile, $modelff);
             //				$model=new TmpXml('search');
             $doc = new TmpDocd('search');
             //				$this->render('admin',array('model'=>$model,'doc'=>$doc,'rr'=>$ii));
             Constants::model()->setCvalue('nstr_' . Yii::app()->user->uid, $modelff->n_str);
             Constants::model()->setCvalue('nfin_' . Yii::app()->user->uid, $modelff->n_fin);
             Constants::model()->setCvalue('nnom_' . Yii::app()->user->uid, $modelff->n_nom);
             Constants::model()->setCvalue('nart_' . Yii::app()->user->uid, $modelff->n_art);
             Constants::model()->setCvalue('nquant_' . Yii::app()->user->uid, $modelff->n_quant);
             Constants::model()->setCvalue('nprice_' . Yii::app()->user->uid, $modelff->n_price);
             Constants::model()->setCvalue('dep_' . Yii::app()->user->uid, $modelff->department);
             Constants::model()->setCvalue('cli_' . Yii::app()->user->uid, $modelff->client);
             $this->render('admin', array('model' => $doc));
         } else {
             $this->render('fform', array('model' => $modelff));
         }
     }
 }
 function __construct(&$fh)
 {
     $this->majorVersion = FileRead::read_USHORT($fh);
     $this->minorVersion = FileRead::read_USHORT($fh);
     $this->defaultVertOriginY = FileRead::read_SHORT($fh);
     $this->numVertOriginYMetrics = FileRead::read_USHORT($fh);
     // actual data
     for ($i = 0; $i < $this->numVertOriginYMetrics; $i++) {
         $glyphIndex = FileRead::read_USHORT($fh);
         $vertOriginY = FileRead::read_SHORT($fh);
         $this->vertOriginYMetrics[] = array("glyphIndex" => $glyphIndex, "vertOriginY" => $vertOriginY);
     }
 }
 static function read_NUMBER(&$fh)
 {
     $b0 = FileRead::read_BYTE($fh);
     // single byte integers
     if (32 <= $b0 && $b0 <= 246) {
         return $b0 - 139;
     }
     // two byte integers
     $b1 = FileRead::read_BYTE($fh);
     if (247 <= $b0 && $b0 <= 250) {
         return 256 * ($b0 - 247) + $b1 + 108;
     }
     if (251 <= $b0 && $b0 <= 259) {
         return -256 * ($b0 - 251) - ($b1 + 108);
     }
     // three byte integers
     $b2 = FileRead::read_BYTE($fh);
     if ($b0 == 28) {
         $v = $b1 << 8 | $b2;
         if ($v > pow(2, 15)) {
             $v -= pow(2, 16);
         }
         return $v;
     }
     // five byte integers
     $b3 = FileRead::read_BYTE($fh);
     $b4 = FileRead::read_BYTE($fh);
     if ($b0 == 29) {
         return $b1 << 24 | $b2 << 16 | $b3 << 8 | $b4;
     } elseif ($b0 == 30) {
         $stop_nibble = 0xf;
         $n1 = -1;
         $n2 = -1;
         $numstring = '';
         while ($n1 != $stop_nibble && $n2 != $stop_nibble) {
             $nibbles = FileRead::read_BYTE($fh);
             //echo dechex($nibbles) . ": {";
             $n1 = $nibbles >> 4;
             //echo "$n1,";
             $n2 = ($nibbles & 0xf) << 4 >> 4;
             //echo "$n2} ";
             // check both nibbles for what they actually mean
             $nibbles = array($n1, $n2);
             foreach ($nibbles as $nibble) {
                 if (0 <= $nibble && $nibble <= 9) {
                     $numstring .= $nibble;
                 } else {
                     switch ($nibble) {
                         case 0xa:
                             $numstring .= ".";
                             break;
                         case 0xb:
                             $numstring .= "E";
                             break;
                         case 0xc:
                             $numstring .= "E-";
                             break;
                             // case(0xd) : { reserved }
                         // case(0xd) : { reserved }
                         case 0xe:
                             $numstring .= "-";
                             break;
                         case 0xf:
                             break;
                     }
                 }
             }
         }
         $real = floatval($numstring);
         //echo "\n returning number conversion of $numstring ($real)\n";
         return $real;
     }
     // fallback.
     echo "error in read_NUMBER, byte pattern ({$b0}) didn't make sense.\n";
     return 0;
 }
 private static function get_TTF_glyph_for_index($font, $char, $index, $matrix = array(0, 0, 1, 0, 0, 1))
 {
     // echo "glyph index for $char: $index\n";
     // step zero: does this char exist?
     if ($index == GlyphFetcher::$NOTSET) {
         $index = $font->get_index($char);
     }
     if ($index === false) {
         return false;
     }
     // there was no cache yet. Perform the real lookup.
     require_once OTTTFONT::$TTFlocation . "ttfglyphdata.php";
     $font->log("This is a TTF font. consulting 'index to location' table.");
     $fh = $font->open();
     $head =& $font->getOTFTableLoader()->get_head_table($font);
     $indexToLocFormat = $head->indexToLocFormat;
     // tells us whether the 'loca' table uses USHORT or ULONG data fields
     // "Index to Location" table, which will tell us where in the "glyf" table we can find the glyph
     $loca =& $font->tables['loca'];
     // "Glyph Data" table, which should give us the glyph's actual outline data (if there is any)
     $glyf =& $font->tables['glyf'];
     // navigate to position $index
     $glyphpointer = 0;
     $next = 0;
     if ($indexToLocFormat == 0) {
         // USHORT entries = seek based on 2 byte jumps (since a USHORT is 16 bit)
         $offset = $loca->offset + $index * 2;
         rewind($fh);
         fseek($fh, $offset);
         // pointer values are stored as half of what they really are in the short table
         $glyphpointer = 2 * FileRead::read_USHORT($fh);
         $next = 2 * FileRead::read_USHORT($fh);
     } elseif ($indexToLocFormat == 1) {
         // ULONG entries = seek based on 4 byte jumps (since a ULONG is 32 bit)
         $step = $index * 4;
         $offset = $loca->offset + $step;
         rewind($fh);
         fseek($fh, $offset);
         // pointer values are stored normally in the long table
         $glyphpointer = FileRead::read_ULONG($fh);
         $next = FileRead::read_ULONG($fh);
     }
     // if the two pointer values are the same, the glyph has no outline
     // (there are a number of invisible characters, mostly spacers).
     $empty = false;
     if ($glyphpointer == $next) {
         $empty = true;
         $font->log("glyph has no outline data in " . $font->fontfilelocation);
     }
     $data = new TTFGlyphData();
     // if there is no outline data, we need to fill in the zero-valued metrics
     if ($empty) {
         $data->xMin = 0;
         $data->yMin = 0;
         $data->xMax = 0;
         $data->yMax = 0;
         $data->height = 0;
         require_once OTTTFont::$GDlocation . "glyphrules.php";
         $data->glyphdata = new Type2GlyphRules();
     } else {
         rewind($fh);
         $offset = $glyf->offset + $glyphpointer;
         $fs = filesize($font->fontfilelocation);
         if ($offset > $fs) {
             echo "ERROR: tried to move the pointer " . ($offset - $fs) . " bytes beyond the end of file!\n";
             return false;
         }
         fseek($fh, $offset);
         // read glyph data (see http://www.microsoft.com/typography/otspec/glyf.htm)
         $data->unitsPerEm = $head->unitsPerEm;
         $numberOfContours = FileRead::read_SHORT($fh);
         // If the number of contours is greater than zero, this is a single glyph;
         // if negative, this is a composite glyph.
         $xMin = FileRead::read_SHORT($fh);
         // Minimum x for coordinate data.
         $yMin = FileRead::read_SHORT($fh);
         // Minimum y for coordinate data.
         $xMax = FileRead::read_SHORT($fh);
         // Maximum x for coordinate data.
         $yMax = FileRead::read_SHORT($fh);
         // Maximum y for coordinate data.
         $width = $xMax - $xMin;
         $height = $yMax - $yMin;
         $data->numberOfContours = $numberOfContours;
         $data->xMin = $xMin;
         $data->yMin = $yMin;
         $data->xMax = $xMax;
         $data->yMax = $yMax;
         $data->width = $width;
         $data->height = $height;
         $font->log("glyph has {$numberOfContours} contours ({$width}x{$height}), x/y min/max: ({$xMin},{$yMin},{$xMax},{$yMax}) in " . $font->fontfilelocation);
         // simple glyph
         if ($numberOfContours >= 0) {
             // first things first: if there is only one contour point, and it's really small, it's probably not actually a glyph
             if ($numberOfContours == 1 && $width < 120 && $height < 120) {
                 return false;
             }
             // read the glyph data
             $endPtsOfContours = array();
             for ($i = 0; $i < $numberOfContours; $i++) {
                 $endPtsOfContours[] = FileRead::read_USHORT($fh);
             }
             $data->endPtsOfContours = $endPtsOfContours;
             // it's much easier to also have access to contour startpoints, rather than just endpoints
             $startPtsOfContours = array(0);
             for ($i = 0; $i < count($endPtsOfContours) - 1; $i++) {
                 $startPtsOfContours[] = $endPtsOfContours[$i] + 1;
             }
             $data->startPtsOfContours = $startPtsOfContours;
             // get instructions
             $instructionLength = FileRead::read_USHORT($fh);
             $data->instructionLength = $instructionLength;
             $instructions = array();
             for ($i = 0; $i < $instructionLength; $i++) {
                 $instructions[] = FileRead::read_BYTE($fh);
             }
             $data->instructions = $instructions;
             // get the coordinate information
             $count = $endPtsOfContours[$numberOfContours - 1] + 1;
             // get all the coordinate flags (code based on Apache's batik java code)
             $data->flags = array();
             for ($flag = 0; $flag < $count; $flag++) {
                 $data->flags[$flag] = FileRead::read_BYTE($fh);
                 if ($data->flag_repeats($flag)) {
                     $repeats = FileRead::read_BYTE($fh);
                     for ($i = 1; $i <= $repeats; $i++) {
                         $data->flags[$flag + $i] = $data->flags[$flag];
                     }
                     $flag += $repeats;
                 }
             }
             // x-coordinates (relative, code based on Apache's batik java code)
             $xCoordinates = array();
             for ($i = 0; $i < $count; $i++) {
                 $x = 0;
                 $xShort = $data->x_is_byte($i);
                 $xDual = $data->x_dual_set($i);
                 // If x-Short Vector is set, xDual describes the sign of the value, with 1 equalling positive and 0 negative.
                 if ($xShort) {
                     if ($xDual) {
                         $x += FileRead::read_BYTE($fh);
                     } else {
                         $x -= FileRead::read_BYTE($fh);
                     }
                 } elseif (!$xDual) {
                     $x += FileRead::read_SHORT($fh);
                 }
                 // correct for offset
                 $xCoordinates[$i] = $x - $xMin;
             }
             // y-coordinates (relative, code based on Apache's batik java code)
             $yCoordinates = array();
             for ($i = 0; $i < $count; $i++) {
                 $y = 0;
                 $yShort = $data->y_is_byte($i);
                 $yDual = $data->y_dual_set($i);
                 // If y-Short Vector is set, yDual describes the sign of the value, with 1 equalling positive and 0 negative.
                 if ($yShort) {
                     if ($yDual) {
                         $y += FileRead::read_BYTE($fh);
                     } else {
                         $y -= FileRead::read_BYTE($fh);
                     }
                 } elseif (!$yDual) {
                     $y += FileRead::read_SHORT($fh);
                 }
                 // correct for offset and flip y coordinate
                 $yCoordinates[$i] = $y - $yMin;
             }
             // bind data and form a glyphrules object
             $data->xCoordinates = $xCoordinates;
             $data->yCoordinates = $yCoordinates;
             $data->formGlyphRules($matrix);
         } else {
             $ARG_1_AND_2_ARE_WORDS = 1;
             // If this is set, the arguments are words; otherwise, they are bytes.
             $ARGS_ARE_XY_VALUES = 2;
             // If this is set, the arguments are xy values; otherwise, they are points.
             $ROUND_XY_TO_GRID = 4;
             // For the xy values if the preceding is true.
             $WE_HAVE_A_SCALE = 8;
             // This indicates that there is a simple scale for the component. Otherwise, scale = 1.0.
             $MORE_COMPONENTS = 32;
             // Indicates at least one more glyph after this one.
             $WE_HAVE_AN_X_AND_Y_SCALE = 64;
             // The x direction will use a different scale from the y direction.
             $WE_HAVE_A_TWO_BY_TWO = 128;
             // There is a 2 by 2 transformation that will be used to scale the component.
             $WE_HAVE_INSTRUCTIONS = 256;
             // Following the last component are instructions for the composite character.
             $USE_MY_METRICS = 512;
             // If set, this forces the aw and lsb (and rsb) for the composite to be equal to those from this original glyph.
             $old_xoffset = 0;
             $old_yoffset = 0;
             $old_xdiff = 0;
             $old_ydiff = 0;
             $last = false;
             $current = false;
             $flags = "";
             do {
                 $flags = FileRead::read_USHORT($fh);
                 $glyphIndex = FileRead::read_USHORT($fh);
                 $arg1 = "";
                 $arg2 = "";
                 // read in argument 1 and 2
                 if (masks($flags, $ARG_1_AND_2_ARE_WORDS)) {
                     $arg1 = FileRead::read_SHORT($fh);
                     $arg2 = FileRead::read_SHORT($fh);
                 } else {
                     $arg1 = FileRead::read_BYTE($fh);
                     $arg2 = FileRead::read_SBYTE($fh);
                 }
                 $xscale = 1;
                 $scale01 = 0;
                 $scale10 = 0;
                 $yscale = 1;
                 if (masks($flags, $WE_HAVE_A_SCALE)) {
                     $xscale = FileRead::read_F2DOT14($fh);
                     $yscale = $xscale;
                 } elseif (masks($flags, $WE_HAVE_AN_X_AND_Y_SCALE)) {
                     $xscale = FileRead::read_F2DOT14($fh);
                     $yscale = FileRead::read_F2DOT14($fh);
                 } elseif (masks($flags, $WE_HAVE_A_TWO_BY_TWO)) {
                     $xscale = FileRead::read_F2DOT14($fh);
                     $scale01 = FileRead::read_F2DOT14($fh);
                     $scale10 = FileRead::read_F2DOT14($fh);
                     $yscale = FileRead::read_F2DOT14($fh);
                 }
                 $xoffset = $arg1;
                 $yoffset = $arg2;
                 // Merge data: if not masked, the arguments indicate how the glyphs link up:
                 // 	- arg1 is the connecting point in the "current" glyph
                 // 	- arg2 is the connecting point in the "next" glyph
                 // We can use these to derive the x/y offset for the linked glyph
                 if (!masks($flags, $ARGS_ARE_XY_VALUES)) {
                     // TODO: this has not yet been implemented
                     trigger_error("point matching not yet implemented\n");
                 }
                 // push the administrative values through.
                 $last = $current;
                 $matrix = array($xoffset, $yoffset, $xscale, $scale01, $scale10, $yscale);
                 $mark = ftell($fh);
                 $current = GlyphFetcher::get_TTF_glyph_for_index($font, $char, $glyphIndex, $matrix);
                 $old_xoffset = $xoffset;
                 $old_yoffset = $yoffset;
                 rewind($fh);
                 fseek($fh, $mark);
                 $data->merge($current);
             } while (masks($flags, $MORE_COMPONENTS));
             // if there are instructions, we read them in but don't do anything with them,
             // because this parser does not process instructions.
             if (masks($flags, $WE_HAVE_INSTRUCTIONS)) {
                 $numInstr = FileRead::read_USHORT($fh);
                 $bytes = array();
                 for ($n = 0; $n < $numInstr; $n++) {
                     $bytes[] = FileRead::read_BYTE($fh);
                 }
             }
         }
     }
     fclose($fh);
     return $data;
 }
示例#5
0
文件: scan.php 项目: Vanzct/AppsAngle
                    $rfiles = array();
                    foreach ($files as $f) {
                        if (strpos($f, $time)) {
                            $rfiles[] = $f;
                        }
                    }
                    $files = $rfiles;
                }
            }
        }
        //print_r($files);
        return array_unique($files);
    }
}
$appname = $_GET["app_name"];
$scanMan = new FileRead();
$scanMan->appname = $appname;
#查询得到要扫描的目录
$app = $scanMan->db->selectAppRootByName($appname);
$scanMan->rootpath = $app["root_path"];
#如果其他人在刷新页面,结束
if ((int) $app["isscanning"] == 1) {
    echo "state:0;其他小伙伴正在执行扫描...";
    return;
}
#设置刷新状态为--刷新中--,让其他人等待
$scanMan->db->updateAppRootIsScanning($appname, 1);
$scandenies_db = $scanMan->db->selectAllScanDenies($appname);
$levels_db = $scanMan->db->selectAppLevel($appname);
$max_create_time_db = $scanMan->db->selectAppQrsCreatetime($appname);
$app["update_time"] = strtotime($app["update_time"]);
示例#6
0
 /**
  * create a cmap format 4 struct based on the data at the filepointer
  */
 static function createCMAPFormat12(&$fh)
 {
     $cmapformat12 = new CMAPFormat12();
     $cmapformat12->offset = $fh;
     FileRead::read_USHORT($fh);
     // reserved for... who knows
     $cmapformat12->length = FileRead::read_ULONG($fh);
     $cmapformat12->language = FileRead::read_ULONG($fh);
     $cmapformat12->nGroups = FileRead::read_ULONG($fh);
     $groups = array();
     for ($n = 0; $n < $cmapformat12->nGroups; $n++) {
         $startCharCode = FileRead::read_ULONG($fh);
         $endCharCode = FileRead::read_ULONG($fh);
         $startGlyphID = FileRead::read_ULONG($fh);
         $groups[] = array('startCharCode' => $startCharCode, 'endCharCode' => $endCharCode, 'startGlyphID' => $startGlyphID);
     }
     $cmapformat12->groups = $groups;
     return $cmapformat12;
 }
示例#7
0
 /**
  * Format 4 is the "segment mapping to delta value" table format. It's relatively
  * straight-forward, except when the glyph map needs to be consulted, in which case
  * it pulls off a crazy pointer arithmetic trick.
  */
 private function contains_format4($character, &$fh)
 {
     $cmapformat4 = CMAPFormat4::createCMAPFormat4($fh);
     // from this point until the start of the next table, every USHORT is an entry in the GlyphIdArray
     $mark = ftell($fh);
     // characters are stored based on their unicode number.
     $c = uniord($character);
     // start looking for the segment of the table that our character should be in, which we will call "i".
     $i = 0;
     while ($i < $cmapformat4->segCount && $cmapformat4->endCount[$i] < $c) {
         $i++;
     }
     // if the character was not found in any segment...
     if ($i >= $cmapformat4->segCount) {
         $this->log("No segment found containing this glyph.");
         return false;
     }
     $this->log("Glyph {$c} should be in segment " . ($i + 1) . " (segment range is " . "[" . $cmapformat4->startCount[$i] . "-" . $cmapformat4->endCount[$i] . "], delta " . $cmapformat4->idDelta[$i] . ", offset " . $cmapformat4->idRangeOffset[$i] . "...");
     // if the following conditional succeeds, our character has a mapping stored implicitly for this
     // segment. However, if that mapping is 0, the character itself is not supported (0 mapping to
     // the NOTDEF glyph.
     if ($cmapformat4->startCount[$i] <= $c) {
         $this->log("Valid segment range, checking whether we need to consult the glyphIdArray...");
         $found = false;
         $index = 0;
         if ($cmapformat4->idRangeOffset[$i] != 0) {
             $this->log("We do. Computing array index and consulting glyphIdArray...");
             /*
             	This is where things get a bit mad...
             
             	If the idRangeOffset value for the segment is not 0, the mapping of character codes relies on glyphIdArray.
             	The character code offset from startCode is added to the idRangeOffset value. This sum is used as an
             	offset from the current location within idRangeOffset itself to index out the correct glyphIdArray value.
             	This obscure indexing trick works because glyphIdArray immediately follows idRangeOffset in the font file.
             
             	The C expression that yields the glyph index, according to Microsoft, is:
             
             		*(idRangeOffset[i]/2 + (c - startCount[i]) + &idRangeOffset[i])
             
             	Try as I might, I couldn't make that do the right thing. Luckily, an alternative function is provided by
             	https://developer.apple.com/fonts/TTRefMan/RM06/Chap6cmap.html:
             
             		glyphindex = idRangeOffset[i] + 2 * (c - startCode[i]) + (Ptr) &idRangeOffset[i]
             
             	This function seems to work quite well. I don't quite understand why, but I'm not going to question something
             	that works.
             */
             $pointer = $cmapformat4->idRangeOffset[$i] + 2 * ($c - $cmapformat4->startCount[$i]) + $cmapformat4->filepointers[$i];
             // zero index?
             if ($pointer == 0) {
                 $this->log("Glyph index was 0, which means it maps to NOTDEF.");
                 return false;
             }
             // if not 0, find the mapped index value.
             $this->log("Glyph index was {$pointer}, checking what the corresponding mapping is.");
             rewind($fh);
             fseek($fh, $pointer);
             $this->log("Set pointer to " . ftell($fh) . " (0x" . strtoupper(dechex(ftell($fh))) . ")");
             // now... again, if this value is zero, the glyph is not actually supported by the font.
             $mapping = FileRead::read_USHORT($fh);
             $this->log("Glyph maps to {$mapping}.");
             $found = $mapping != 0;
             $this->log("This font " . ($found ? "supports" : "does not support") . " this glyph.");
             // and then the final bit of crazy: if the mapping was not zero, the character's
             // actual index in the glyph data table is [mapping + delta (modulo 2^16)].
             $index = ($cmapformat4->idDelta[$i] + $mapping + 65536) % 65536;
         } else {
             $this->log("We don't. Computing direct mapping...");
             // again, the glyph data table index for this glyph is computed modulo 2^16
             $index = ($cmapformat4->idDelta[$i] + $c + 65536) % 65536;
             $this->log("Glyph maps to {$index}.");
             $found = $index != 0;
             $this->log("This font " . ($found ? "supports" : "does not support") . " this glyph.");
         }
         // if everything checks out, we signal success by returning the glyph's index
         return $index;
     }
     // and one final possibility for definitely not supporting a glyph:
     $this->log("First segment start is already higher than our character's value. That means this font does not support this glyph.");
     return false;
 }
示例#8
0
<?php

require 'includes/header.php';
require 'classes/Autoloader.php';
?>

<h1 id="schoolH1">School Records</h1> <br><br>
<div id="schoolRecords">
<?php 
$fileName = 'schoolData.csv';
$mode = 'r';
$dictionary = new FileRead();
$dictionaryNames = $dictionary->fileRead('hd2013/varlist.csv', $mode);
$csvFile = new FileRead();
$records = $csvFile->fileRead($fileName, $mode, TRUE);
if (empty($_GET)) {
    echo MakeLinks::linkMaker($records, 'university', 'INSTNM');
} else {
    echo MakeTable::tableMaker($records[$_GET['university']]);
}
?>
</div>
<div id="recordResult">
	<h1>Select a School</h1>
</div>
<?php 
require 'includes/footer.php';
示例#9
0
 static function read_F2DOT14(&$filehandle)
 {
     $val = FileRead::read_SHORT($filehandle);
     $twos = $val << 2 >> 2;
     // 2's complement means the value right now represents -(pow(2, 14) - $nominator), so convert back:
     $nominator = -(-$twos - 16384);
     // IEEE 14 bit fraction means the divisor is 2^14
     $frac = $nominator / 16384;
     $dec = $val << 1 >> 1;
     $sign = $dec != $val ? -1 : 1;
     $dec = $sign * ($dec >> 14);
     return $dec + $frac;
 }
 function set_base_values(&$fh)
 {
     $this->byteposition = ftell($fh);
     //echo "table start = " . $this->byteposition . " (".dechex($this->byteposition).")\n";
     $this->count = FileRead::read_USHORT($fh);
     // are there any elements?
     if ($this->count == 0) {
         $this->nexttable = ftell($fh);
     } else {
         //echo "count is " . $this->count . "\n";
         $offSize = FileRead::read_BYTE($fh);
         //echo "offSize = " . $offSize . "\n";
         $this->offSize = $offSize;
         $this->offsets = array();
         $blocksize = ($this->count + 1) * $offSize;
         $block = fread($fh, $blocksize);
         // you could optimise this by using some nice code with a switch statement and compact source, and it would run slower.
         // normally, this would not be a big problem, but when it's about the speed at which individual letters are plucked from a font,
         // 10ms per letter adds up. Very quickly. "Things not to do" include:
         //
         //   - imploding the unpack instead of grabbing [1]
         //   - using a single for(...) loop with a switch(offsize) for the offset reading
         //   - split datablock to byte array first, using preg_split, and then reading (series of) bytes instead of substrings
         //
         $offsets = array();
         $i = 0;
         if ($offSize == 1) {
             for ($i = 0; $i < $blocksize; $i++) {
                 $up = unpack('C', substr($block, $i, 1));
                 $offsets[] = $up[1];
             }
         } elseif ($offSize == 2) {
             for ($i = 0; $i < $blocksize; $i = $i + 2) {
                 $up = unpack('n', substr($block, $i, 2));
                 $offsets[] = $up[1];
             }
         } elseif ($offSize == 3) {
             for ($i = 0; $i < $blocksize; $i = $i + 3) {
                 $byte = unpack('C', substr($block, $i, 1));
                 $short = unpack('n', substr($block, $i + 1, 2));
                 $offsets[] = 0x10000 * $byte[1] + $short[1];
             }
         } elseif ($offSize == 4) {
             for ($i = 0; $i < $blocksize; $i = $i + 4) {
                 $up = unpack('N', substr($block, $i, 4));
                 $offsets[] = $up[1];
             }
         } else {
             echo "ERROR: offSize is unknown size: {$offSize}\n";
             exit(-1);
         }
         $this->offsets = $offsets;
         // the filepointer for the data start is set at 1 byte before the actual data
         //  (see 16 March 2000 version of Adobe CFF spec, pp10, right after Table 7)
         $this->datastart = ftell($fh) - 1;
         // the next table can be found with a calculation mostly derived from the example on page 50 of the CFF specification
         $offsetcount = count($this->offsets);
         $offset_and_data = $this->offSize * $offsetcount + $this->offsets[$offsetcount - 1];
         // = last entry in the offsets array			(after, fp at start of next table)
         $this->nexttable = $this->byteposition + 2 + $offset_and_data;
         //echo "next table starts at " . $this->nexttable . " (".dechex($this->nexttable).")\n";
     }
 }