Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 48 additions & 46 deletions fretboard/fretboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
font_size: 15
height: 300
width: 250
spacing: 30
horizontal_spacing: 30
vertical_spacing: 30
orientation: portrait

nut:
Expand All @@ -38,6 +39,7 @@
string:
color: darkslategray
size: 3
same_width: False

marker:
border_color: darkslategray
Expand Down Expand Up @@ -80,32 +82,36 @@ def add_string_label(self, string, label, font_color=None):
self.strings[string].label = label
self.strings[string].font_color = font_color

def add_marker(self, string, fret, color=None, label=None, font_color=None):
def add_marker(self, string, fret, color=None, label=None, font_color=None, label_adjust=(0, 0)):
self.markers.append(attrdict.AttrDict({
'fret': fret,
'string': string,
'color': color,
'label': label,
'font_color': font_color,
'label_adjust': label_adjust,
}))

def wipe(self):
self.markers = []

def calculate_layout(self):
if self.style.drawing.orientation == 'portrait':
neck_width = self.style.drawing.width - (self.style.drawing.spacing * 2.25)
neck_length = self.style.drawing.height - (self.style.drawing.spacing * 2)
neck_width = self.style.drawing.width - (self.style.drawing.horizontal_spacing * 2.25)
neck_length = self.style.drawing.height - (self.style.drawing.vertical_spacing * 2)

layout_width = neck_width
layout_height = neck_length
layout_x = self.style.drawing.spacing
layout_y = self.style.drawing.spacing * 1.5
layout_x = self.style.drawing.horizontal_spacing
layout_y = self.style.drawing.vertical_spacing * 1.5
else:
neck_width = self.style.drawing.height - (self.style.drawing.spacing * 2.25)
neck_length = self.style.drawing.width - (self.style.drawing.spacing * 2)
neck_width = self.style.drawing.height - (self.style.drawing.horizontal_spacing * 2.25)
neck_length = self.style.drawing.width - (self.style.drawing.vertical_spacing * 2)

layout_width = neck_length
layout_height = neck_width
layout_x = self.style.drawing.spacing * 1.5
layout_y = self.style.drawing.spacing
layout_x = self.style.drawing.horizontal_spacing * 1.5
layout_y = self.style.drawing.vertical_spacing

# Bounding box of our fretboard
self.layout.update({
Expand Down Expand Up @@ -157,7 +163,11 @@ def draw_strings(self):
for index, string in enumerate(self.strings):

# Offset the first and last strings, so they're not drawn outside the edge of the nut.
string_width = self.style.string.size - ((self.style.string.size * 1 / (len(self.strings) * 1.5)) * index)
if self.style.string.same_width:
string_width = self.style.string.size
else:
string_width = self.style.string.size - ((self.style.string.size * 1 / (len(self.strings) * 1.5)) * index)

offset = 0
str_index = self.get_layout_string_index(index)

Expand All @@ -168,12 +178,12 @@ def draw_strings(self):

if self.style.drawing.orientation == 'portrait':
label_x = self.layout.x + (self.layout.string_space * str_index) + offset
label_y = self.layout.y + self.style.drawing.font_size - self.style.drawing.spacing
label_y = self.layout.y + self.style.drawing.font_size - self.style.drawing.vertical_spacing
string_start = (label_x, self.layout.y)
string_stop = (label_x, self.layout.y + self.layout.height)

elif self.style.drawing.orientation == 'landscape':
label_x = self.layout.x + self.style.drawing.font_size - self.style.drawing.spacing
label_x = self.layout.x + self.style.drawing.font_size - self.style.drawing.horizontal_spacing
label_y = self.layout.y + (self.layout.string_space * str_index) + offset
string_start = (self.layout.x, label_y)
string_stop = (self.layout.x + self.layout.width, label_y)
Expand Down Expand Up @@ -230,7 +240,7 @@ def draw_inlays(self):
inlay_dist = self.style.nut.size + self.layout.fret_space * index - self.layout.fret_space / 2

if self.style.drawing.orientation == 'portrait':
x = self.style.drawing.spacing - (self.style.inlays.radius * 4)
x = self.style.drawing.horizontal_spacing - (self.style.inlays.radius * 4)
y = self.layout.y + inlay_dist
else:
x = self.layout.x + inlay_dist
Expand Down Expand Up @@ -272,11 +282,11 @@ def draw_inlays(self):
def draw_fret_label(self):
if self.frets[0] > 0:
if self.style.drawing.orientation == 'portrait':
x = self.layout.width + self.style.drawing.spacing + self.style.inlays.radius
x = self.layout.width + self.style.drawing.horizontal_spacing + self.style.inlays.radius
y = self.layout.y + self.style.nut.size + (self.style.drawing.font_size * .2)
else:
x = self.layout.x + self.style.nut.size - (self.style.drawing.font_size * 0.75)
y = self.layout.height + self.style.drawing.spacing + self.style.drawing.font_size * 1.0
y = self.layout.height + self.style.drawing.vertical_spacing + self.style.drawing.font_size * 1.0

self.drawing.add(
self.drawing.text('{0}fr'.format(self.frets[0]),
Expand All @@ -290,6 +300,20 @@ def draw_fret_label(self):
)
)

def draw_marker_label(self, label, position):
if label is not None:
self.drawing.add(
self.drawing.text(label,
insert=position,
font_family=self.style.drawing.font_family,
font_size=self.style.drawing.font_size,
font_weight='bold',
fill=self.style.marker.font_color,
text_anchor='middle',
alignment_baseline='central'
)
)

def draw_markers(self):
for marker in self.markers:
if isinstance(marker.string, (list, tuple)):
Expand All @@ -302,7 +326,7 @@ def draw_marker(self, marker):
marker_string = self.get_layout_string_index(marker.string)

if self.style.drawing.orientation == 'portrait':
x = self.style.drawing.spacing + (self.layout.string_space * marker_string)
x = self.style.drawing.horizontal_spacing + (self.layout.string_space * marker_string)
y = sum((
self.layout.y,
self.style.nut.size,
Expand All @@ -316,7 +340,7 @@ def draw_marker(self, marker):
(self.layout.fret_space * (marker.fret - self.frets[0])) - (
self.layout.fret_space / 2)
))
y = self.style.drawing.spacing + (self.layout.string_space * marker_string)
y = self.style.drawing.vertical_spacing + (self.layout.string_space * marker_string)

self.drawing.add(
self.drawing.circle(
Expand All @@ -329,18 +353,7 @@ def draw_marker(self, marker):
)

# Draw the label
if marker.label is not None:
self.drawing.add(
self.drawing.text(marker.label,
insert=(x, y),
font_family=self.style.drawing.font_family,
font_size=self.style.drawing.font_size,
font_weight='bold',
fill=self.style.marker.font_color,
text_anchor='middle',
alignment_baseline='central'
)
)
self.draw_marker_label(marker.label, (x+marker.label_adjust[0], y+marker.label_adjust[1]))

def draw_barre(self, marker):
marker_string_0 = self.get_layout_string_index(marker.string[0])
Expand All @@ -353,8 +366,8 @@ def draw_barre(self, marker):
(self.layout.fret_space * (marker.fret - self.frets[0])) - (
self.layout.fret_space / 2)
))
start = (self.style.drawing.spacing + (self.layout.string_space * marker_string_0), y)
end = (self.style.drawing.spacing + (self.layout.string_space * marker_string_1), y)
start = (self.style.drawing.horizontal_spacing + (self.layout.string_space * marker_string_0), y)
end = (self.style.drawing.horizontal_spacing + (self.layout.string_space * marker_string_1), y)

else:
x = sum((
Expand All @@ -363,8 +376,8 @@ def draw_barre(self, marker):
(self.layout.fret_space * (marker.fret - self.frets[0])) - (
self.layout.fret_space / 2)
))
start = (x, self.style.drawing.spacing + (self.layout.string_space * marker_string_1))
end = (x, self.style.drawing.spacing + (self.layout.string_space * marker_string_0))
start = (x, self.style.drawing.horizontal_spacing + (self.layout.string_space * marker_string_1))
end = (x, self.style.drawing.horizontal_spacing + (self.layout.string_space * marker_string_0))

# Lines don't support borders, so fake it by drawing
# a slightly larger line behind it.
Expand All @@ -388,18 +401,7 @@ def draw_barre(self, marker):
)
)

if marker.label is not None:
self.drawing.add(
self.drawing.text(marker.label,
insert=start,
font_family=self.style.drawing.font_family,
font_size=self.style.drawing.font_size,
font_weight='bold',
fill=self.style.marker.font_color,
text_anchor='middle',
alignment_baseline='central'
)
)
self.draw_marker_label(marker.label, (start[0] + marker.label_adjust[0], start[1] + marker.label_adjust[1]))

def draw(self):
self.drawing = svgwrite.Drawing(size=(
Expand Down