Diffs
GD_Tab_Guitar/trunk/GD/Tab/GD_Tab_Guitar.php
@@ -0,0 +1,596 @@
+<?php
+/**
+ * GD_Tab_Guitar generates guitar tab scores.
+ * This module is inspired by GD::Tab::Guitar (perl module), and it's almost its copy.
+ *
+ *
+ * SYNOPSIS
+ *
+ * $gtr = new GD_Tab_Guitar();
+ *
+ * // print png image
+ * print $gtr->chord('D#sus4')->png();
+ *
+ * // other tab generate
+ * $gtr->generate('G7', array(1,0,0,0,2,3))->png();
+ *
+ * // above fret style (1st string to 6th string) is unfamiliar to most guitarists.
+ * // you can also specify the reversed and familiar style like this:
+ * $gtr->generate('G7', '320001')->png();
+ *
+ * // if you want to specify some mute strings, put "x" character.
+ * $gtr->generate('D7', 'x00212')->png();
+ *
+ * // set color
+ * $gtr->setColor(255, 0, 0);
+ *
+ * // set background-color and no interlace
+ * $gtr->setBgcolor(200, 200, 200);
+ * $gtr->setInterlaced(0);
+ *
+ * // all tabs image save to file.
+ * foreach ($gtr->allChords() as $chord) {
+ * $gtr->chord($chord)->png("$chord.png");
+ * }
+ *
+ *
+ * @author NAKAMURA Satoru <clonedoppelganger@gmail.com>
+ * @license New BSD License
+ * @version 0.0.1
+ * @see http://search.cpan.org/dist/GD-Tab-Guitar/
+ * @see http://search.cpan.org/~tateno/GD-Tab-Ukulele-0.01/
+ */
+class GD_Tab_Guitar
+{
+
+ const GD_TINY_FONT = 1;
+
+ const GD_SMALL_FONT = 2;
+
+ protected static $lines = array(
+ array(5, 15, 46, 15),
+ array(5, 21, 46, 21),
+ array(5, 27, 46, 27),
+ array(5, 33, 46, 33),
+ array(5, 39, 46, 39),
+ array(5, 45, 46, 45),
+ array(4, 15, 4, 45),
+ array(6, 15, 6, 45),
+ array(14, 15, 14, 45),
+ array(22, 15, 22, 45),
+ array(30, 15, 30, 45),
+ array(38, 15, 38, 45),
+ );
+
+ protected static $chordLists = array(
+ 'C' => 'x32010',
+ 'C6' => 'x32210',
+ 'C6(9)' => 'x32233',
+ 'CM7' => 'x32000',
+ 'CM7(9)' => 'x30000',
+ 'C7' => 'x32310',
+ 'C7(b5)' => 'x34310',
+ 'C7(b9)' => 'x32323',
+ 'C7(b9,13)' => 'x21214',
+ 'C7(9)' => 'x3233x',
+ 'C7(9,13)' => 'x32335',
+ 'C7(#9)' => 'x3234x',
+ 'C7(#11)' => 'x1213x',
+ 'C7(b13)' => 'x1211x',
+ 'C7(13)' => 'x1221x',
+ 'Cm' => 'x35543',
+ 'Cm6' => 'x31213',
+ 'Cm6(9)' => 'x3124x',
+ 'CmM7' => 'x31003',
+ 'Cm7' => 'x31313',
+ 'Cm7(b5)' => 'x3434x',
+ 'Cm7(9)' => 'x3133x',
+ 'Cm7(9,11)' => 'x31331',
+ 'Cdim' => 'x3424x',
+ 'Caug' => 'x3211x',
+ 'Caug7' => 'x323x4',
+ 'Csus4' => 'x33011',
+ 'C7sus4' => 'x33311',
+ 'Cadd9' => 'x32030',
+ 'C#' => 'x43121',
+ 'C#6' => 'x4332x',
+ 'C#6(9)' => 'x43344',
+ 'C#M7' => 'x43111',
+ 'C#M7(9)' => 'x4354x',
+ 'C#7' => 'x4342x',
+ 'C#7(b5)' => 'x4542x',
+ 'C#7(b9)' => 'x43434',
+ 'C#7(b9,13)' => 'x43436',
+ 'C#7(9)' => 'x4344x',
+ 'C#7(9,13)' => 'x43445',
+ 'C#7(#9)' => 'x4345x',
+ 'C#7(#11)' => 'x4546x',
+ 'C#7(b13)' => 'x2322x',
+ 'C#7(13)' => 'x2332x',
+ 'C#m' => 'x46654',
+ 'C#m6' => 'x42324',
+ 'C#m6(9)' => 'x4234x',
+ 'C#mM7' => 'x4211x',
+ 'C#m7' => 'x42100',
+ 'C#m7(b5)' => 'x4545x',
+ 'C#m7(9)' => 'x4244x',
+ 'C#m7(9,11)' => 'x42442',
+ 'C#dim' => 'x4535x',
+ 'C#aug' => 'x4322x',
+ 'C#aug7' => 'x2322x',
+ 'C#sus4' => 'x46674',
+ 'C#7sus4' => 'x44422',
+ 'C#add9' => 'x43141',
+ 'D' => 'xx0232',
+ 'D6' => 'xx0202',
+ 'D6(9)' => 'x54455',
+ 'DM7' => 'xx0222',
+ 'DM7(9)' => 'xx0220',
+ 'D7' => 'xx0212',
+ 'D7(b5)' => 'xx0112',
+ 'D7(b9)' => 'x5454x',
+ 'D7(b9,13)' => 'x54547',
+ 'D7(9)' => 'xx0210',
+ 'D7(9,13)' => 'x54557',
+ 'D7(#9)' => 'x5456x',
+ 'D7(#11)' => 'xx0112',
+ 'D7(b13)' => 'x3433x',
+ 'D7(13)' => 'x3443x',
+ 'Dm' => 'xx0231',
+ 'Dm6' => 'xx0201',
+ 'Dm6(9)' => 'x5345x',
+ 'DmM7' => 'x5322x',
+ 'Dm7' => 'xx0211',
+ 'Dm7(b5)' => 'xx0111',
+ 'Dm7(9)' => 'x5355x',
+ 'Dm7(9,11)' => 'x53553',
+ 'Ddim' => 'xx0101',
+ 'Daug' => 'xx0332',
+ 'Daug7' => 'xx0312',
+ 'Dsus4' => 'x55033',
+ 'D7sus4' => 'xx0213',
+ 'Dadd9' => 'xx0230',
+ 'Eb' => 'xx1343',
+ 'Eb6' => 'xx1313',
+ 'Eb6(9)' => 'x65566',
+ 'EbM7' => 'xx1333',
+ 'EbM7(9)' => 'xx1331',
+ 'Eb7' => 'xx1323',
+ 'Eb7(b5)' => 'xx1223',
+ 'Eb7(b9)' => 'xx1020',
+ 'Eb7(b9,13)' => 'x65658',
+ 'Eb7(9)' => 'xx1021',
+ 'Eb7(9,13)' => 'x65668',
+ 'Eb7(#9)' => 'xx1022',
+ 'Eb7(#11)' => 'xx1223',
+ 'Eb7(b13)' => 'x4544x',
+ 'Eb7(13)' => 'x4554x',
+ 'Ebm' => 'xx1342',
+ 'Ebm6' => 'xx1312',
+ 'Ebm6(9)' => 'x6456x',
+ 'EbmM7' => 'xx1332',
+ 'Ebm7' => 'xx1322',
+ 'Ebm7(b5)' => 'xx1222',
+ 'Ebm7(9)' => 'x6466x',
+ 'Ebm7(9,11)' => 'xx1121',
+ 'Ebdim' => 'xx1212',
+ 'Ebaug' => 'xx1003',
+ 'Ebaug7' => 'x2102x',
+ 'Ebsus4' => 'xx1344',
+ 'Eb7sus4' => 'xx1324',
+ 'Ebadd9' => 'xx1341',
+ 'E' => '022100',
+ 'E6' => '022120',
+ 'E6(9)' => 'xx2122',
+ 'EM7' => '02110x',
+ 'EM7(9)' => '021102',
+ 'E7' => '020100',
+ 'E7(b5)' => 'xx2334',
+ 'E7(b9)' => '020101',
+ 'E7(b9,13)' => '020131',
+ 'E7(9)' => '020132',
+ 'E7(9,13)' => '020122',
+ 'E7(#9)' => '020103',
+ 'E7(#11)' => '6x675x',
+ 'E7(b13)' => '020110',
+ 'E7(13)' => '020120',
+ 'Em' => '022000',
+ 'Em6' => '022020',
+ 'Em6(9)' => '022022',
+ 'EmM7' => '021000',
+ 'Em7' => '020000',
+ 'Em7(b5)' => '0x2333',
+ 'Em7(9)' => '020002',
+ 'Em7(9,11)' => 'xx2232',
+ 'Edim' => '012020',
+ 'Eaug' => '03211x',
+ 'Eaug7' => '032130',
+ 'Esus4' => '022200',
+ 'E7sus4' => '020200',
+ 'Eadd9' => '024100',
+ 'F' => '133211',
+ 'F6' => '1x323x',
+ 'F6(9)' => '100011',
+ 'FM7' => 'xx3210',
+ 'FM7(9)' => '1x2010',
+ 'F7' => '131211',
+ 'F7(b5)' => '1x120x',
+ 'F7(b9)' => 'xx1212',
+ 'F7(b9,13)' => '1x1232',
+ 'F7(9)' => '131213',
+ 'F7(9,13)' => '1x123x',
+ 'F7(#9)' => '131214',
+ 'F7(#11)' => '101201',
+ 'F7(b13)' => '1x122x',
+ 'F7(13)' => '1x123x',
+ 'Fm' => '133111',
+ 'Fm6' => '133131',
+ 'Fm6(9)' => '1xx133',
+ 'FmM7' => '13211x',
+ 'Fm7' => '131111',
+ 'Fm7(b5)' => '1x110x',
+ 'Fm7(9)' => '131113',
+ 'Fm7(9,11)' => '131313',
+ 'Fdim' => '1x0101',
+ 'Faug' => 'xx3221',
+ 'Faug7' => '1x1221',
+ 'Fsus4' => '133311',
+ 'F7sus4' => '131311',
+ 'Fadd9' => 'xx3213',
+ 'F#' => '244322',
+ 'F#6' => '2x434x',
+ 'F#6(9)' => '2x112x',
+ 'F#M7' => 'xx4321',
+ 'F#M7(9)' => '2x312x',
+ 'F#7' => '242322',
+ 'F#7(b5)' => '2x231x',
+ 'F#7(b9)' => '212020',
+ 'F#7(b9,13)' => 'x1204x',
+ 'F#7(9)' => '21212x',
+ 'F#7(9,13)' => '21213x',
+ 'F#7(#9)' => '242325',
+ 'F#7(#11)' => '2x231x',
+ 'F#7(b13)' => '2x233x',
+ 'F#7(13)' => '2x234x',
+ 'F#m' => '244222',
+ 'F#m6' => '244242',
+ 'F#m6(9)' => 'xx1224',
+ 'F#mM7' => '24322x',
+ 'F#m7' => '242222',
+ 'F#m7(b5)' => '2x221x',
+ 'F#m7(9)' => '242224',
+ 'F#m7(9,11)' => '20210x',
+ 'F#dim' => '2x121x',
+ 'F#aug' => 'xx4332',
+ 'F#aug7' => '2x2332',
+ 'F#sus4' => '244422',
+ 'F#7sus4' => '242422',
+ 'F#add9' => 'xx4324',
+ 'G' => '320003',
+ 'G6' => '320000',
+ 'G6(9)' => '3x223x',
+ 'GM7' => '320002',
+ 'GM7(9)' => '3x423x',
+ 'G7' => '320001',
+ 'G7(b5)' => '3x342x',
+ 'G7(b9)' => 'x2313x',
+ 'G7(b9,13)' => '3x3100',
+ 'G7(9)' => '353435',
+ 'G7(9,13)' => '3x3200',
+ 'G7(#9)' => '353436',
+ 'G7(#11)' => '3x342x',
+ 'G7(b13)' => '3x344x',
+ 'G7(13)' => '323000',
+ 'Gm' => '355333',
+ 'Gm6' => '3x233x',
+ 'Gm6(9)' => 'xx2335',
+ 'GmM7' => '354333',
+ 'Gm7' => '353333',
+ 'Gm7(b5)' => '3x332x',
+ 'Gm7(9)' => '353335',
+ 'Gm7(9,11)' => '3x321x',
+ 'Gdim' => '3x232x',
+ 'Gaug' => '321003',
+ 'Gaug7' => '3x3443',
+ 'Gsus4' => '330013',
+ 'G7sus4' => '330011',
+ 'Gadd9' => '3x0233',
+ 'G#' => '431114',
+ 'G#6' => '431111',
+ 'G#6(9)' => '4x334x',
+ 'G#M7' => 'xx6543',
+ 'G#M7(9)' => '4x534x',
+ 'G#7' => '464544',
+ 'G#7(b5)' => '4x453x',
+ 'G#7(b9)' => 'x3424x',
+ 'G#7(b9,13)' => '4x4211',
+ 'G#7(9)' => '464546',
+ 'G#7(9,13)' => '4x4311',
+ 'G#7(#9)' => '464547',
+ 'G#7(#11)' => '4x453x',
+ 'G#7(b13)' => '4x455x',
+ 'G#7(13)' => '434111',
+ 'G#m' => '466444',
+ 'G#m6' => 'xx1101',
+ 'G#m6(9)' => 'xx3446',
+ 'G#mM7' => 'xx1103',
+ 'G#m7' => '464444',
+ 'G#m7(b5)' => 'x20102',
+ 'G#m7(9)' => '464446',
+ 'G#m7(9,11)' => '4x432x',
+ 'G#dim' => '4x343x',
+ 'G#aug' => 'xx6554',
+ 'G#aug7' => '4x4554',
+ 'G#sus4' => '466644',
+ 'G#7sus4' => '464644',
+ 'G#add9' => 'xx6546',
+ 'A' => 'x02220',
+ 'A6' => 'x02222',
+ 'A6(9)' => 'x02202',
+ 'AM7' => 'x02120',
+ 'AM7(9)' => 'x02100',
+ 'A7' => 'x02020',
+ 'A7(b5)' => 'x0102x',
+ 'A7(b9)' => 'x02323',
+ 'A7(b9,13)' => 'x05322',
+ 'A7(9)' => 'x02423',
+ 'A7(9,13)' => 'x05422',
+ 'A7(#9)' => '575658',
+ 'A7(#11)' => 'x01023',
+ 'A7(b13)' => 'x02021',
+ 'A7(13)' => 'x02022',
+ 'Am' => 'x02210',
+ 'Am6' => 'x02212',
+ 'Am6(9)' => 'xx4557',
+ 'AmM7' => 'x02110',
+ 'Am7' => 'x02010',
+ 'Am7(b5)' => 'x01213',
+ 'Am7(9)' => 'x02000',
+ 'Am7(9,11)' => 'x02433',
+ 'Adim' => 'x01212',
+ 'Aaug' => 'x03221',
+ 'Aaug7' => 'x03021',
+ 'Asus4' => 'x02230',
+ 'A7sus4' => 'x02030',
+ 'Aadd9' => 'x02200',
+ 'Bb' => 'x13331',
+ 'Bb6' => 'x13333',
+ 'Bb6(9)' => 'x10011',
+ 'BbM7' => 'x13231',
+ 'BbM7(9)' => 'x10211',
+ 'Bb7' => 'x13131',
+ 'Bb7(b5)' => 'x12131',
+ 'Bb7(b9)' => 'x10101',
+ 'Bb7(b9,13)' => 'x10103',
+ 'Bb7(9)' => 'x1011x',
+ 'Bb7(9,13)' => 'x10113',
+ 'Bb7(#9)' => 'x1012x',
+ 'Bb7(#11)' => 'x10130',
+ 'Bb7(b13)' => 'x13132',
+ 'Bb7(13)' => 'x13133',
+ 'Bbm' => 'x13321',
+ 'Bbm6' => 'x1302x',
+ 'Bbm6(9)' => 'xx5668',
+ 'BbmM7' => 'x13221',
+ 'Bbm7' => 'x13121',
+ 'Bbm7(b5)' => 'x1212x',
+ 'Bbm7(9)' => 'x13111',
+ 'Bbm7(9,11)' => '6x654x',
+ 'Bbdim' => 'x12020',
+ 'Bbaug' => 'x10443',
+ 'Bbaug7' => 'x14132',
+ 'Bbsus4' => 'x13341',
+ 'Bb7sus4' => 'x13141',
+ 'Bbadd9' => 'x13311',
+ 'B' => 'x24442',
+ 'B6' => 'x24444',
+ 'B6(9)' => 'x21122',
+ 'BM7' => 'x24342',
+ 'BM7(9)' => 'x2132x',
+ 'B7' => 'x21202',
+ 'B7(b5)' => 'x2324x',
+ 'B7(b9)' => 'x2121x',
+ 'B7(b9,13)' => 'x21214',
+ 'B7(9)' => 'x2122x',
+ 'B7(9,13)' => 'x21224',
+ 'B7(#9)' => 'x2123x',
+ 'B7(#11)' => 'x2324x',
+ 'B7(b13)' => 'x24243',
+ 'B7(13)' => 'x24244',
+ 'Bm' => 'x24432',
+ 'Bm6' => 'x2413x',
+ 'Bm6(9)' => 'x2012x',
+ 'BmM7' => 'x20332',
+ 'Bm7' => 'x20202',
+ 'Bm7(b5)' => 'x2323x',
+ 'Bm7(9)' => 'x2022x',
+ 'Bm7(9,11)' => 'x20220',
+ 'Bdim' => 'x2313x',
+ 'Baug' => 'x2100x',
+ 'Baug7' => 'x25243',
+ 'Bsus4' => 'x24452',
+ 'B7sus4' => 'x22202',
+ 'Badd9' => 'x24422',
+ );
+
+ protected static $synonyms = array(
+ 'C#' => 'Db',
+ 'Eb' => 'D#',
+ 'F#' => 'Gb',
+ 'G#' => 'Ab',
+ 'Bb' => 'A#',
+ );
+
+ protected static $synonymsRe = '/^([CFG]#|[EB]b)/';
+
+ private static $initialized = false;
+
+ private $bgcolor;
+
+ private $color;
+
+ private $interlaced;
+
+ private $im;
+
+ public function __construct()
+ {
+ if (!self::$initialized) {
+ self::init();
+ }
+ $this->bgcolor = array(255, 255, 255);
+ $this->color = array(0, 0, 0);
+ $this->interlaced = true;
+ }
+
+ public function setBgcolor($r, $g, $b)
+ {
+ $this->bgcolor = array($r, $g, $b);
+ }
+
+ public function setColor($r, $g, $b)
+ {
+ $this->color = array($r, $g, $b);
+ }
+
+ public function setInterlaced($interlaced)
+ {
+ $this->interlaced = $interlaced;
+ }
+
+ public function chord($chord)
+ {
+ return $this->generate($chord, $this->getFrets($chord));
+ }
+
+ public function getFrets($chord)
+ {
+ if (!isset(self::$chordLists[$chord])) {
+ throw new Exception("undefined chord $chord");
+ }
+ return str_split(self::$chordLists[$chord]);
+ }
+
+ public function generate($chord, $frets = null)
+ {
+ if ($frets !== null) {
+ $frets = is_array($frets) ? array_reverse($frets) : array_reverse(str_split($frets));
+ }
+
+ $this->im = imagecreate(52, 56);
+ $bgcolor = imagecolorallocate($this->im, $this->bgcolor[0], $this->bgcolor[1], $this->bgcolor[2]);
+ $color = imagecolorallocate($this->im, $this->color[0], $this->color[1], $this->color[2]);
+
+ if ($this->interlaced) {
+ imagecolortransparent($this->im, $bgcolor);
+ imageinterlace($this->im, true);
+ }
+
+ $this->drawLine($color);
+
+ $fretMax = max(preg_grep('/^\d+$/', $frets));
+
+ if ($fretMax > 5) {
+ imagefilledrectangle($this->im, 4, 15, 6, 45, $bgcolor);
+ $fretNum = $fretMax - 5;
+
+ foreach ($frets as &$fret) {
+ if (strtolower($fret) !== 'x') {
+ $fret -= $fretNum;
+ }
+ }
+
+ for ($n = 0; $n <= 4; $n++) {
+ imagestring($this->im, self::GD_TINY_FONT, 9 * $n + 4, 47, $fretNum + 1, $color);
+ $fretNum++;
+ }
+ }
+
+ $i = 0;
+ foreach ($frets as &$fret) {
+ if (strtolower($fret) === 'x') {
+ imageline($this->im, 0, 14 + 6 * $i, 2, 16 + 6 * $i, $color);
+ imageline($this->im, 2, 14 + 6 * $i, 0, 16 + 6 * $i, $color);
+ } elseif ($fret > 0) {
+ imagefilledrectangle($this->im,
+ 9 + 8 * ($fret - 1),
+ 14 + 6 * $i,
+ 11 + 8 * ($fret - 1),
+ 16 + 6 * $i, $color
+ );
+ }
+ $i++;
+ }
+
+ imagestring($this->im, self::GD_SMALL_FONT, 4, 0, $chord, $color);
+
+ return $this;
+ }
+
+ public function png($path = null)
+ {
+ return $this->output('png', $path);
+ }
+
+ public function jpeg($path = null)
+ {
+ return $this->output('jpeg', $path);
+ }
+
+ public function gif($path = null)
+ {
+ return $this->output('gif', $path);
+ }
+
+ public function allChords()
+ {
+ return array_keys(self::$chordLists);
+ }
+
+ protected function output($type, $path = null)
+ {
+ switch ($type) {
+ case 'png':
+ $func = 'imagepng';
+ break;
+ case 'jpeg':
+ $func = 'imagejpeg';
+ break;
+ case 'gif':
+ $func = 'imagegif';
+ break;
+ default:
+ $func = 'imagepng';
+ }
+ if ($path === null) {
+ ob_start();
+ call_user_func($func, $this->im);
+ $contents = ob_get_clean();
+ imagedestroy($this->im);
+ return $contents;
+ } else {
+ call_user_func($func, $this->im, $path);
+ imagedestroy($this->im);
+ }
+ }
+
+ protected function drawLine($color)
+ {
+ foreach (self::$lines as $line) {
+ imageline($this->im, $line[0], $line[1], $line[2], $line[3], $color);
+ }
+ }
+
+ protected static function init()
+ {
+ foreach (self::$chordLists as $chord => $frets) {
+ if (preg_match(self::$synonymsRe, $chord, $matches)) {
+ $matche = $matches[1];
+ $sameChord = preg_replace('/^' . $matche . '/', self::$synonyms[$matche], $chord);
+ self::$chordLists[$sameChord] = $frets;
+ }
+ }
+ self::$initialized = true;
+ }
+
+}
属性に変更があったパス: GD_Tab_Guitar/trunk/GD/Tab/GD_Tab_Guitar.php
___________________________________________________________________
追加: svn:executable
+ *