This allows PHP scripts to read and/or generate these types of files.backup
parent
2c69d3a685
commit
603a469896
@ -1,203 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
namespace monoformat { |
|
||||||
|
|
||||||
enum SectionType : int { |
|
||||||
case AlwaysDrawn = 1; |
|
||||||
case TimeBasedDrawn = 2; |
|
||||||
case CustomFont = 32; |
|
||||||
} |
|
||||||
|
|
||||||
enum ElementType : int { |
|
||||||
case Image = 1; |
|
||||||
case Animation = 2; |
|
||||||
case HScrollImage = 3; |
|
||||||
case VScrollImage = 4; |
|
||||||
case Line = 5; |
|
||||||
case ClippedText = 16; |
|
||||||
case HScrollText = 17; |
|
||||||
case CurrentTime = 32; |
|
||||||
} |
|
||||||
|
|
||||||
enum LineStyle : int { |
|
||||||
case Solid = 0; |
|
||||||
} |
|
||||||
|
|
||||||
class Element { |
|
||||||
public function serialize() { |
|
||||||
return ""; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class HScrollTextElement extends Element { |
|
||||||
public $x = 0; |
|
||||||
public $y = 0; |
|
||||||
public $width = 0; |
|
||||||
public $height = 0; |
|
||||||
public $flags = 0; |
|
||||||
public $scrollSpeed = 0; |
|
||||||
public $fontIndex = 0; |
|
||||||
public $text = ""; |
|
||||||
|
|
||||||
public function serialize() { |
|
||||||
$len = strlen($this->text); |
|
||||||
$result = pack("vvvvvCCvv", |
|
||||||
17, |
|
||||||
$this->x, |
|
||||||
$this->y, |
|
||||||
$this->width, |
|
||||||
$this->height, |
|
||||||
$this->flags, |
|
||||||
$this->scrollSpeed, |
|
||||||
$this->fontIndex, |
|
||||||
$len); |
|
||||||
$result .= (string) $this->text; |
|
||||||
if ($len % 4 != 0) { |
|
||||||
$n = 4 - ($len % 4); |
|
||||||
for ($i = 0; $i < $n; ++$i) { |
|
||||||
$result .= chr(0); |
|
||||||
} |
|
||||||
} |
|
||||||
return $result; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class CurrentTimeElement extends Element { |
|
||||||
public $x = 0; |
|
||||||
public $y = 0; |
|
||||||
public $width = 0; |
|
||||||
public $height = 0; |
|
||||||
public $fontIndex = 0; |
|
||||||
public $utcOffset = 0; |
|
||||||
public $flags = 0; |
|
||||||
|
|
||||||
public function serialize() { |
|
||||||
$result = pack("vvvvvvvv", |
|
||||||
32, |
|
||||||
$this->x, |
|
||||||
$this->y, |
|
||||||
$this->width, |
|
||||||
$this->height, |
|
||||||
$this->fontIndex, |
|
||||||
$this->utcOffset, |
|
||||||
$this->flags); |
|
||||||
return $result; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class Section { |
|
||||||
public function serialize() { |
|
||||||
return ""; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class AlwaysDrawnSection extends Section { |
|
||||||
public $drawOnFront = false; |
|
||||||
public $drawOnBack = false; |
|
||||||
public $clearBeforeDrawing = false; |
|
||||||
public $elements = []; |
|
||||||
|
|
||||||
public function serialize() { |
|
||||||
$flags = 0; |
|
||||||
if ($this->drawOnFront) { |
|
||||||
$flags |= 0x01; |
|
||||||
} |
|
||||||
if ($this->drawOnBack) { |
|
||||||
$flags |= 0x02; |
|
||||||
} |
|
||||||
if ($this->clearBeforeDrawing) { |
|
||||||
$flags |= 0x04; |
|
||||||
} |
|
||||||
$inner = pack("vv", $flags, count($this->elements)); |
|
||||||
foreach ($this->elements as $element) { |
|
||||||
$inner .= $element->serialize(); |
|
||||||
} |
|
||||||
$len = strlen($inner) + 4; |
|
||||||
$len = substr(pack("V", $len), 0, 3); |
|
||||||
return pack("C", 1) . $len . $inner; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class File { |
|
||||||
public $sections = []; |
|
||||||
|
|
||||||
public function serialize() { |
|
||||||
$nSections = count($this->sections); |
|
||||||
$result = "\xAF\x7E\x2B\x63"; |
|
||||||
$result .= pack("Vvv", 1, $nSections, 0); |
|
||||||
foreach ($this->sections as $section) { |
|
||||||
$result .= $section->serialize(); |
|
||||||
} |
|
||||||
return $result; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace monoformat |
|
||||||
|
|
||||||
namespace { |
|
||||||
|
|
||||||
$roomName= "BOOL"; |
|
||||||
|
|
||||||
$data = json_decode(file_get_contents("https://cfp.cttue.de/tdf5/schedule/export/schedule.json"), true); |
|
||||||
$talks = []; |
|
||||||
$now = new DateTimeImmutable("now"); |
|
||||||
foreach ($data["schedule"]["conference"]["days"] as $day) { |
|
||||||
foreach ($day["rooms"][$roomName] as $t) { |
|
||||||
[$h, $m] = explode(":", $t["duration"]); |
|
||||||
$duration = $h * 3600 + $m * 60; |
|
||||||
$duration = DateInterval::createFromDateString("$duration sec"); |
|
||||||
$talk = [ |
|
||||||
"date" => new DateTimeImmutable($t["date"]), |
|
||||||
"duration" => $duration, |
|
||||||
"title" => $t["title"], |
|
||||||
]; |
|
||||||
$talkEnd = $talk["date"]->add($talk["duration"]); |
|
||||||
if ($talkEnd < $now) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
if ($talk["date"] > $now && count($talks) > 2) { |
|
||||||
break; |
|
||||||
} |
|
||||||
array_push($talks, $talk); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
$elements = []; |
|
||||||
|
|
||||||
function putText($x, $y, $width, $height, $text) { |
|
||||||
global $elements; |
|
||||||
|
|
||||||
$e = new monoformat\HScrollTextElement(); |
|
||||||
$e->x = $x; |
|
||||||
$e->y = $y; |
|
||||||
$e->width = $width; |
|
||||||
$e->height = $height; |
|
||||||
$e->flags = 0; |
|
||||||
$e->scrollSpeed = 15; |
|
||||||
$e->fontIndex = 0; |
|
||||||
$e->text = $text; |
|
||||||
array_push($elements, $e); |
|
||||||
} |
|
||||||
|
|
||||||
$i = 0; |
|
||||||
foreach ($talks as $talk) { |
|
||||||
putText(10, $i * 20, 25, 20, $talk["date"]->format("H:i")); |
|
||||||
putText(35, $i * 20, 85, 20, $talk["title"]); |
|
||||||
++$i; |
|
||||||
} |
|
||||||
|
|
||||||
$section = new monoformat\AlwaysDrawnSection(); |
|
||||||
$section->drawOnFront = true; |
|
||||||
$section->drawOnBack = true; |
|
||||||
$section->clearBeforeDrawing = true; |
|
||||||
$section->elements = $elements; |
|
||||||
|
|
||||||
$file = new monoformat\File(); |
|
||||||
array_push($file->sections, $section); |
|
||||||
|
|
||||||
Header("Content-Type: application/octet-stream"); |
|
||||||
|
|
||||||
print($file->serialize()); |
|
||||||
} // global |
|
||||||
|
|
||||||
?> |
|
||||||
@ -0,0 +1,43 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace monoformat { |
||||||
|
|
||||||
|
function isBitSet(int $value, int $bit) { |
||||||
|
if ($bit < 0 || $bit >= (PHP_INT_SIZE * 8)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
$mask = 1 << $bit; |
||||||
|
return ($value & $mask) == $mask; |
||||||
|
} |
||||||
|
|
||||||
|
function setBit(int &$value, int $bit) { |
||||||
|
if ($bit < 0 || $bit >= (PHP_INT_SIZE * 8)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
$mask = 1 << $bit; |
||||||
|
$value |= $mask; |
||||||
|
} |
||||||
|
|
||||||
|
function unsetBit(int &$value, int $bit) { |
||||||
|
if ($bit < 0 || $bit >= (PHP_INT_SIZE * 8)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
$mask = 1 << $bit; |
||||||
|
$value &= ~$mask; |
||||||
|
} |
||||||
|
|
||||||
|
function maybeSetBit(int &$value, int $bit, int $set) { |
||||||
|
if ($bit < 0 || $bit >= (PHP_INT_SIZE * 8)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
$mask = 1 << $bit; |
||||||
|
if ($set) { |
||||||
|
$value |= $mask; |
||||||
|
} else { |
||||||
|
$value &= ~$mask; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace monoformat |
||||||
|
|
||||||
|
?> |
||||||
@ -0,0 +1,210 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace monoformat { |
||||||
|
|
||||||
|
include_once("monoformat_bithelpers.php"); |
||||||
|
|
||||||
|
trait FlagStruct { |
||||||
|
public static function fromJSON(array $json) { |
||||||
|
$myClass = static::class; |
||||||
|
$reflect = new \ReflectionClass($myClass); |
||||||
|
$properties = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC); |
||||||
|
$result = new $myClass(); |
||||||
|
foreach ($properties as $property) { |
||||||
|
$name = $property->getName(); |
||||||
|
if (array_key_exists($name, $json)) { |
||||||
|
$result->$name = (bool) $json[$name]; |
||||||
|
} |
||||||
|
} |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function toJSON(): array { |
||||||
|
$result = []; |
||||||
|
$myClass = static::class; |
||||||
|
$reflect = new \ReflectionClass($myClass); |
||||||
|
$properties = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC); |
||||||
|
foreach ($properties as $property) { |
||||||
|
$name = $property->getName(); |
||||||
|
$result[$name] = $this->$name; |
||||||
|
} |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
enum SectionType : int { |
||||||
|
case AlwaysDrawn = 1; |
||||||
|
case TimeBasedDrawn = 2; |
||||||
|
case MultiTimeBasedDrawn = 3; |
||||||
|
case ExpiryDate = 31; |
||||||
|
case CustomFont = 32; |
||||||
|
|
||||||
|
public static function fromName(string $name): SectionType { |
||||||
|
foreach (self::cases() as $case) { |
||||||
|
if ($case->name === $name) { |
||||||
|
return $case; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new \ValueError("$name is not a valid backing value for enum " . self::class); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
enum ElementType : int { |
||||||
|
case Image = 1; |
||||||
|
case Animation = 2; |
||||||
|
case HScrollImage = 3; |
||||||
|
case VScrollImage = 4; |
||||||
|
case Line = 5; |
||||||
|
case Box = 6; |
||||||
|
case ClippedText = 16; |
||||||
|
case HScrollText = 17; |
||||||
|
//case VScrollText = 18; |
||||||
|
case CurrentTime = 32; |
||||||
|
|
||||||
|
public static function fromName(string $name): SectionType { |
||||||
|
foreach (self::cases() as $case) { |
||||||
|
if ($case->name === $name) { |
||||||
|
return $case; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new \ValueError("$name is not a valid backing value for enum " . self::class); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ScrollFlags { |
||||||
|
use FlagStruct; |
||||||
|
|
||||||
|
public bool $endless = false; |
||||||
|
public bool $invertDirection = false; |
||||||
|
public bool $padBefore = false; |
||||||
|
public bool $padAfter = false; |
||||||
|
|
||||||
|
public static function fromBitField(int $bitfield): ScrollFlags { |
||||||
|
$result = new ScrollFlags(); |
||||||
|
$result->endless = isBitSet($bitfield, 0); |
||||||
|
$result->invertDirection = isBitSet($bitfield, 1); |
||||||
|
$result->padBefore = isBitSet($bitfield, 2); |
||||||
|
$result->padAfter = isBitSet($bitfield, 3); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function toBitField(): int { |
||||||
|
$result = 0; |
||||||
|
maybeSetBit($result, 0, $this->endless); |
||||||
|
maybeSetBit($result, 1, $this->invertDirection); |
||||||
|
maybeSetBit($result, 2, $this->padBefore); |
||||||
|
maybeSetBit($result, 3, $this->padAfter); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
enum LineStyle : int { |
||||||
|
case Solid = 0; |
||||||
|
|
||||||
|
public static function fromName(string $name): SectionType { |
||||||
|
foreach (self::cases() as $case) { |
||||||
|
if ($case->name === $name) { |
||||||
|
return $case; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new \ValueError("$name is not a valid backing value for enum " . self::class); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class LineFlags { |
||||||
|
use FlagStruct; |
||||||
|
|
||||||
|
public bool $dark = false; |
||||||
|
|
||||||
|
public static function fromBitField(int $bitfield): LineFlags { |
||||||
|
$result = new LineFlags(); |
||||||
|
$result->dark = isBitSet($bitfield, 0); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function toBitField(): int { |
||||||
|
$result = 0; |
||||||
|
maybeSetBit($result, 0, $this->dark); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
enum FillPatternStyle : int { |
||||||
|
case Solid = 0; |
||||||
|
|
||||||
|
public static function fromName(string $name): SectionType { |
||||||
|
foreach (self::cases() as $case) { |
||||||
|
if ($case->name === $name) { |
||||||
|
return $case; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new \ValueError("$name is not a valid backing value for enum " . self::class); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class FillFlags { |
||||||
|
use FlagStruct; |
||||||
|
|
||||||
|
public bool $dark = false; |
||||||
|
|
||||||
|
public static function fromBitField(int $bitfield): FillFlags { |
||||||
|
$result = new FillFlags(); |
||||||
|
$result->dark = isBitSet($bitfield, 0); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function toBitField(): int { |
||||||
|
$result = 0; |
||||||
|
maybeSetBit($result, 0, $this->dark); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TextFlags { |
||||||
|
use FlagStruct; |
||||||
|
|
||||||
|
public bool $dark = false; |
||||||
|
|
||||||
|
public static function fromBitField(int $bitfield): TextFlags { |
||||||
|
$result = new TextFlags(); |
||||||
|
$result->dark = isBitSet($bitfield, 0); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function toBitField(): int { |
||||||
|
$result = 0; |
||||||
|
maybeSetBit($result, 0, $this->dark); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TimeDisplayFlags { |
||||||
|
use FlagStruct; |
||||||
|
|
||||||
|
public bool $use12h = false; |
||||||
|
public bool $showHours = false; |
||||||
|
public bool $showMinutes = false; |
||||||
|
public bool $showSeconds = false; |
||||||
|
|
||||||
|
public static function fromBitField(int $bitfield): TimeDisplayFlags { |
||||||
|
$result = new TimeDisplayFlags(); |
||||||
|
$result->use12h = isBitSet($bitfield, 0); |
||||||
|
$result->showHours = isBitSet($bitfield, 1); |
||||||
|
$result->showMinutes = isBitSet($bitfield, 2); |
||||||
|
$result->showSeconds = isBitSet($bitfield, 3); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function toBitField(): int { |
||||||
|
$result = 0; |
||||||
|
maybeSetBit($result, 0, $this->use12h); |
||||||
|
maybeSetBit($result, 1, $this->showHours); |
||||||
|
maybeSetBit($result, 2, $this->showMinutes); |
||||||
|
maybeSetBit($result, 3, $this->showSeconds); |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace monoformat |
||||||
|
|
||||||
|
?> |
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue